Integrating Stripe

This guide will help you configure a Stripe payment gateway.

Requirements

To follow this tutorial, you should be familiar with the Stripe API and the Stripe Dashboard. You also need to have access to the Partner Portal.

Steps

Integrating and configuring a Stripe payment gateway is a 5-step process:

Step 1: Configure payment on the Partner Portal

PlatformOS handles the communication with many payment gateways for you behind the scenes.
This guide shows you how to properly configure and process payments with Stripe.

First of all you need to establish a connection between platformOS and Stripe.
To do that, you first need to obtain your Stripe API keys.

Knowing your Stripe API Keys, head to your instance details in Partner Portal and click on the
Integrations button at the top. On the next page click on the Manage Stripe button.
Fill out the form with your test API keys and save it. Alternatively you can use the JSON example below to update your configuration manually.

"payment_gateways": {
  "stripe": {
    "countries": ["US"],
    "currencies": ["USD"],
    "live_login": "",
    "test_login": null,
    "live_mode_enabled": false,
    "test_mode_enabled": "",
    "live_publishable_key": "",
    "test_publishable_key": ""
    }
  }

Step 2: Fetch information about payment gateway with GraphQL

Under the hood Partner Portal created a new PaymentGateway object, that can be accessed with GraphQL.
Fetch publishable_key add pass it to the Stripe Checkout script to properly generate the credit card token.

query get_payment_gateway {
  payment_gateways(
    mode: test
    for_current_mode: false
  ) {
    id
    payment_methods {
      id
    }
    test_publishable_key
    current_mode_publishable_key
  }
}

If your instance operates in test mode, you can use current_mode_publishable_key, but it is fine to use
test_publishable_key which should return the same value (which was previously set in Partner Portal).
You also need to fetch the id of payment method that is used to separate different types of payments like Credit Card, ACH, PayPal, etc.

Step 3: Create minimal working payment example

Create a basic form that accepts the token from Stripe Checkout
script and use it to charge the provided Credit Card.

You will find the code for the following example in the platformOS example project repository.
Web version to play with the example is accessible here.


---
name: simple_payment_form
resource: Payment
redirect_to: /payments
fields:
  credit_card_token:
  with_charge:
  payer_id:
    validation:
      presence: true
  payment_method_id:
    validation:
      presence: true
  currency:
    validation:
      presence: true
  total_amount:
    validation:
      presence: true
      numericality:
        greater_than: 0
flash_notice: Payment successful!
flash_alert: Please fix validation errors
default_payload: |-
  {
    "credit_card_token": "{{ context.params.stripeToken }}",
    "with_charge": true
  }
---
{%- graphql p = 'get_payment_gateway' -%}

{% assign pub_key = p.payment_gateways.first.test_publishable_key %}
{% assign payment_method_id = p.payment_gateways[0].payment_methods[0].id %}
{% assign amount = 5.99 %}
{% assign amount_cents = amount | times: 100 %}

{%- form -%}
  {% if form_builder.errors.base != blank %}
    <div class="form-error">{{ form_builder.errors.base }}</div>
  {% endif %}

  <input name="{{ form_builder.fields.payment_method_id.name }}" type="hidden" value="{{ p.payment_gateways[0].payment_methods[0].id }}">
  <input name="{{ form_builder.fields.currency.name }}" type="hidden" value="USD">
  <input name="{{ form_builder.fields.total_amount.name }}" type="hidden" value="{{amount}}">
  <input name="{{ form_builder.fields.payer_id.name }}" type="hidden" value="{{current_user.id }}">

  <script async
    src="https://checkout.stripe.com/checkout.js" class="stripe-button"
    data-key="{{ pub_key }}"
    data-amount="{{ amount_cents }}"
    data-name="Example platformOS Marketplace"
    data-description="Example charge"
    data-image="https://stripe.com/img/documentation/checkout/marketplace.png"
    data-locale="auto"
    data-zip-code="true">
  </script>
{% endform %}

In the example above you can see script tag inserted at the end of the form filter.
It is provided by Stripe and can be found in the Integrating Checkout Guide.
There are multiple custom options that you can use to fit the desired user experience.
The main purpose of this script is sending provided credit card details to Stripe and pass over the token generated by Stripe.
Token is inserted as hidden input stripeToken that is then converted in default_payload to required credit_card_token.
Another attribute set in the default payload: "with_charge": true tells our platform to immediately send
Charge Request, otherwise, payment would remain authorized but not captured.
This is useful in two-step type payment processes when you first authorize payment and capture/release at a later time.

Payment form configuration has multiple configuration options. The essentials used in the example are as follows:

Attribute Required Description
credit_card_token required token generated by Stripe script
with_charge optional flag telling platformOS to charge payment or just authorized it
payer_id required platformOS user ID
payment_method_id required id of payment method used to identify processing protocol
currency required Currency in which you want your payment amount to be processed
total_amount required the amount charged. Note that this is not amount cents.

For more information about attributes of payment see the documentation for the
Payment object.

Stripe checkout has its own methods of validation and verification of credit cards that are encoded within
the JavaScript plugin, but some validation is processed upon authorization. All errors are appended to
the form_builder.errors.base object and can be accessed as in the example above.
Visit the Stripe Testing page to find credit card numbers
that can be used to test your integration and payment validation.

Step 4: Create payment list

To check the state of the payment, use the (payments)[/api-reference/graphql/g/operation/query#payments] query.
Example below demonstrates how to fetch the last five payments together with the payment status and payer.

query get_payments {
  payments(
    per_page: 5
    ) {
      results {
        id
        state
        total_amount_cents
        payer {
          id
          name
      }
    }
  }
}

The query above can be used within any page or partial as in the exapmle below.
Make sure that payment states in the list match those in your
Stripe Dashboard Payments panel to confirm your integration is working properly.

  <h4>List of last five test payments:</h4>
  {% graphql g = "get_payments" %}
  <table>
      <tr>
        <th>ID</th>
        <th>State</th>
        <th>Payer</th>
        <th>Amount</th>
      </tr>
    {% for payment in  g.payments.results %}
      <tr>
        <td>{{ payment.id }}</td>
        <td>{{ payment.state }}</td>
        <td>{{ payment.payer.name }}</td>
        <td>{{ payment.total_amount_cents | pricify_cents }}</td>
      </tr>
    {% endfor %}
  </table>

Step 5: Fetch Credit Card

When you created the payment in step 2, you used the Stripe token to store a Credit Card first,
then use the stored credit card to process payment. This approach let's you reuse the card for future payments.
You can fetch CreditCard attribues with a GraphQL query:

  query get_credit_cards($user_id: ID) {
    credit_cards(user_id: $user_id) {
      id
      token
      payment_method_id
    }
  }

In the example above you fetch payment_method_id, id, and token that you can use to create future payments with this credit card stored in Stripe.

Alternative way of payment using stored credit card is described in: Processing Payments with GraphQL Mutations

Questions?

We are always happy to help with any questions you may have. Check out our Help page, or contact us.