Stripe Payment Intents gateway guide

Additional notes
Stripe Payment Intents utilizes the Stripe Payment Intents API. Use it if you want access to the newest features, such as 3D Secure 2. If you want to use the legacy Stripe Charges API, see the Stripe Gateway.
Stripe now supports 3rd party 3DS2 solutions. Stripe merchants can use Spreedly’s Gateway Specific 3DS2 solution for Stripe Payment Intents or Spreedly 3DS2 Global.

Be sure to set the attempt_3dsecure flag to true in the transaction request if you are using Stripe Payment Intents for gateway specific 3DS authentication. If you forget to include this field on your request, you may see the following error message: 'Received unexpected 3DS authentication response, but a 3DS initiation flag was not included in the request.'
This gateway supports Level 2 and Level 3 transaction processing via Spreedly. If you are interested in Level 2 or Level 3 transaction support, please contact the gateway to confirm that your account is enabled for these processing types. Please let us know if there are any specific parameters you would like to have enabled.

Adding a Stripe Payment Intents gateway

To add a Stripe Payment Intents gateway you just need to supply a login, which is your API key at Stripe.

curl https://core.spreedly.com/v1/gateways.xml \
  -u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
  -H 'Content-Type: application/xml' \
  -d '<gateway>
        <gateway_type>stripe_payment_intents</gateway_type>
        <login>your restricted api key</login>
      </gateway>'
<gateway>
  <token>5kepJOAe0wB4OeZ026vgTsMXdGv</token>
  <gateway_type>stripe_payment_intents</gateway_type>
  <name>Stripe Payment Intents</name>
  <description nil="true"/>
  <merchant_profile_key nil="true"/>
  <sub_merchant_key nil="true"/>
  <characteristics>
    <supports_purchase type="boolean">true</supports_purchase>
    <supports_authorize type="boolean">true</supports_authorize>
    <supports_capture type="boolean">true</supports_capture>
    <supports_credit type="boolean">true</supports_credit>
    <supports_general_credit type="boolean">false</supports_general_credit>
    <supports_void type="boolean">true</supports_void>
    <supports_adjust type="boolean">false</supports_adjust>
    <supports_verify type="boolean">true</supports_verify>
    <supports_reference_purchase type="boolean">false</supports_reference_purchase>
    <supports_purchase_via_preauthorization type="boolean">false</supports_purchase_via_preauthorization>
    <supports_offsite_purchase type="boolean">true</supports_offsite_purchase>
    <supports_offsite_authorize type="boolean">false</supports_offsite_authorize>
    <supports_offsite_synchronous_purchase type="boolean">false</supports_offsite_synchronous_purchase>
    <supports_offsite_synchronous_authorize type="boolean">false</supports_offsite_synchronous_authorize>
    <supports_3dsecure_purchase type="boolean">true</supports_3dsecure_purchase>
    <supports_3dsecure_authorize type="boolean">true</supports_3dsecure_authorize>
    <supports_3dsecure_2_mpi_purchase type="boolean">false</supports_3dsecure_2_mpi_purchase>
    <supports_3dsecure_2_mpi_authorize type="boolean">false</supports_3dsecure_2_mpi_authorize>
    <supports_store type="boolean">true</supports_store>
    <supports_remove type="boolean">true</supports_remove>
    <supports_fraud_review type="boolean">false</supports_fraud_review>
    <supports_network_tokenization type="boolean">true</supports_network_tokenization>
    <supports_populate_mit_fields type="boolean">false</supports_populate_mit_fields>
    <supports_inquire_by_gateway_transaction_id type="boolean">false</supports_inquire_by_gateway_transaction_id>
    <supports_inquire_by_order_id type="boolean">false</supports_inquire_by_order_id>
    <supports_transaction_retry type="boolean">true</supports_transaction_retry>
    <supports_stored_stored_credentials type="boolean">false</supports_stored_stored_credentials>
    <supports_card_scheme_ntid type="boolean">true</supports_card_scheme_ntid>
    <supports_3dsecure_2_purchase type="boolean">true</supports_3dsecure_2_purchase>
    <supports_3dsecure_2_authorize type="boolean">true</supports_3dsecure_2_authorize>
    <supports_stored_credentials type="boolean">true</supports_stored_credentials>
  </characteristics>
  <credentials>
  </credentials>
  <gateway_settings>
    <webhook_id nil="true"/>
    <transaction_id_management_enabled>false</transaction_id_management_enabled>
  </gateway_settings>
  <gateway_specific_fields>
    <gateway_specific_field>receipt_email</gateway_specific_field>
    <gateway_specific_field>radar_session_id</gateway_specific_field>
    <gateway_specific_field>skip_radar_rules</gateway_specific_field>
    <gateway_specific_field>application_fee</gateway_specific_field>
    <gateway_specific_field>stripe_account</gateway_specific_field>
    <gateway_specific_field>metadata</gateway_specific_field>
    <gateway_specific_field>idempotency_key</gateway_specific_field>
    <gateway_specific_field>reason</gateway_specific_field>
    <gateway_specific_field>refund_application_fee</gateway_specific_field>
    <gateway_specific_field>refund_fee_amount</gateway_specific_field>
    <gateway_specific_field>reverse_transfer</gateway_specific_field>
    <gateway_specific_field>account_id</gateway_specific_field>
    <gateway_specific_field>customer_id</gateway_specific_field>
    <gateway_specific_field>validate</gateway_specific_field>
    <gateway_specific_field>make_default</gateway_specific_field>
    <gateway_specific_field>cancellation_reason</gateway_specific_field>
    <gateway_specific_field>capture_method</gateway_specific_field>
    <gateway_specific_field>confirm</gateway_specific_field>
    <gateway_specific_field>confirmation_method</gateway_specific_field>
    <gateway_specific_field>customer</gateway_specific_field>
    <gateway_specific_field>description</gateway_specific_field>
    <gateway_specific_field>moto</gateway_specific_field>
    <gateway_specific_field>off_session</gateway_specific_field>
    <gateway_specific_field>on_behalf_of</gateway_specific_field>
    <gateway_specific_field>payment_method_types</gateway_specific_field>
    <gateway_specific_field>return_email</gateway_specific_field>
    <gateway_specific_field>return_url</gateway_specific_field>
    <gateway_specific_field>save_payment_method</gateway_specific_field>
    <gateway_specific_field>setup_future_usage</gateway_specific_field>
    <gateway_specific_field>statement_descriptor</gateway_specific_field>
    <gateway_specific_field>statement_descriptor_suffix</gateway_specific_field>
    <gateway_specific_field>transfer_amount</gateway_specific_field>
    <gateway_specific_field>transfer_destination</gateway_specific_field>
    <gateway_specific_field>transfer_group</gateway_specific_field>
    <gateway_specific_field>application_fee_amount</gateway_specific_field>
    <gateway_specific_field>request_three_d_secure</gateway_specific_field>
    <gateway_specific_field>error_on_requires_action</gateway_specific_field>
    <gateway_specific_field>network_transaction_id</gateway_specific_field>
    <gateway_specific_field>claim_without_transaction_id</gateway_specific_field>
    <gateway_specific_field>fulfillment_date</gateway_specific_field>
    <gateway_specific_field>event_type</gateway_specific_field>
    <gateway_specific_field>modal_challenge</gateway_specific_field>
    <gateway_specific_field>idempotent_request</gateway_specific_field>
    <gateway_specific_field>merchant_reference</gateway_specific_field>
    <gateway_specific_field>customer_reference</gateway_specific_field>
    <gateway_specific_field>shipping_address_zip</gateway_specific_field>
    <gateway_specific_field>shipping_from_zip</gateway_specific_field>
    <gateway_specific_field>shipping_amount</gateway_specific_field>
    <gateway_specific_field>line_items</gateway_specific_field>
  </gateway_specific_fields>
  <payment_methods>
    <payment_method>credit_card</payment_method>
    <payment_method>third_party_token</payment_method>
    <payment_method>bank_account</payment_method>
    <payment_method>stripe_apm</payment_method>
    <payment_method>google_pay</payment_method>
    <payment_method>apple_pay</payment_method>
  </payment_methods>
  <state>retained</state>
  <redacted type="boolean">false</redacted>
  <sandbox type="boolean">false</sandbox>
  <mode>default</mode>
  <created_at type="dateTime">2023-09-13T21:10:38Z</created_at>
  <updated_at type="dateTime">2023-09-13T21:10:38Z</updated_at>
</gateway>

To learn more about creating and managing gateways in our Marketplace, review the Gateway user guide. For gateways not included in the Marketplace, review the steps below.

Create a gateway

Visit your Connections area to review all gateways and add new ones. When creating your gateways, select the gateway name and authentication mode (if prompted) before completing required fields. Select ☑️Sandbox to create a gateway in Sandbox mode, for processing test card data and transactions in your Spreedly environment.

Stripe Payment Intents gateways can be created in Default mode or Connect mode.

Default mode

Stripe Payment Intents gateways in Default mode only require the login field, which is Stripe's API key value, available in the API keys section of your Stripe developer Workbench. Spreedly requires the use of Restricted API Key authentication and recommends provisioning restricted keys for all Stripe Payment Intents gateways. Review and create your Stripe API keys by visiting the Workbench and selecting Manage on the API keys section of the page. Create your restricted API key using Spreedly's RAK application in the Stripe App Marketplace. Other fields and gateway settings are optional and described in this gateway guide.

Enter your API restricted key (rk_...) to the Login field. To run successful payment transactions with Stripe, the restricted key must have the following WRITE permissions:

  • Permissions: Charges, Customers, PaymentIntents, PaymentMethods, SetupIntents, Tokens, Webhook Endpoints (Read)
  • Connect permissions: Charges, Customers, PaymentIntents, PaymentMethods, SetupIntents, Tokens

When saving a new Stripe Payment Intents gateway, double check whether the restricted key was created in Test mode or production. If Test, the gateway must be created in Sandbox mode with Spreedly by checking the Sandbox flag in our app and passing "rk_test...". If production, you will only be able to create a production gateway successfully using "rk_live...", and should leave the Sandbox flag unchecked. Stripe will block test credentials created using production credentials, and block production credentials created using test credentials. Attempted transactions will fail.

Stripe Payment Intents with Stripe Connect

Spreedly offers two versions of Stripe Connect on the Stripe Payment Intents Gateway. The first is where a merchant can establish a Stripe Connect relationship through Spreedly and the other is if you are a platform and merchants register Stripe Connect accounts with you. If you are unsure if you are a direct merchant or platform, then navigate to your Stripe Dashboard and check whether you have a list of Connect Accounts or a “Get Started” button, which would prompt you to set up a Platform Profile. If you have the “Get Started” button then you are a Merchant, and if you have a list of Connect Accounts then you would qualify as a Platform.

Stripe Connect for merchants

We recommend testing your integration using a Test environment first, then when you’re ready to go live, create a new environment to link to Stripe in Production Mode.

Follow these steps to get started:

  1. Visit the Marketplace area in your selected environment.
  2. Select the Connect authentication mode for Stripe Payment Intents.
  3. View on the “Stripe Connect” area on the settings page.
  4. Select Sandbox or Production, and click "Connect".
  5. Fill in the information presented on the Stripe hosted page that will appear. Based on the email address that you input, Stripe will be able to tell if you are creating a new account or if the email is linked to an existing account that you would like to connect to your Spreedly account.
  6. Use the below instructions to create a Stripe Payment Intents Gateway Token

Once you connect your Stripe account to an environment you can then create a new Stripe PI gateways under that environment to transact under Stripe Connect.

curl https://core.spreedly.com/v1/gateways.xml \
  -u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
  -H 'Content-Type: application/xml' \
  -d '<gateway>
        <gateway_type>stripe_payment_intents</gateway_type>
        <mode>connect</mode>
      </gateway>'

If you are a platform who has onboarded with Stripe Connect and you try to use Stripe Connect for payouts, then your transactions will fail and you will receive a 422 error message with one of the error messages below. If this happens, please refer to adding a Stripe Payment Intents gateway and unlink your Spreedly account via your Stripe dashboard.

Error 1: Direct Charges (Using Access Token of Platform 2 and Stripe-Account Header Connect Account)
- Error message: "You cannot access the connected accounts of your platform's connected accounts."

Error 2: Destination Charges Using Platform 2 Access Token with tranfer_data[destination]=acct_* (Custom Connect account owned by Platform 2)
- Error message: "You cannot make a destination charge on a connected account. You must either make the request on your own account (by using your platform's API key, and not using the `Stripe-Account` parameter), or remove the `destination` parameter."

Error 3: Using Secret Key Platform 1 with Stripe-Account Header for Platform 2 and tranfer_data[destination]=acct_* (Custom Connect account owned by Platform 2)
- Error message: "You cannot make a destination charge on a connected account. You must either make the request on your own account (by using your platform's API key, and not using the `Stripe-Account` parameter), or remove the `destination` parameter."

Error 4: Secret Key for Platform 1 Stripe Account Header for Platform 2 (charge created on Platform 2), Transfer created using destination to Connect Account of Platform 2
- Error message: "Cannot create transfers on behalf of a Standard connected account."

Stripe Connect for platforms

If you are a platform that has merchants connected to you in Stripe and would like to set up a gateway with a connected endpoint then you can follow the below steps:

  1. Complete the authentication flow outside of Spreedly to establish a Stripe Connect relationship between the platform account and the merchant account.
  2. Create a Connect Webhook for the platform account in the Stripe Dashboard under Developers > Webhooks or Developers > Workbench > Webhooks. This should have:
  3. Create a Stripe Payment Intents gateway at Spreedly with the platform’s Stripe Restricted Key, the connect webhook id, and the connect webhook signing secret.
  4. When performing a transaction on the gateway pass the account key of the merchant, it starts with the prefix acct, via the stripe_account GSF. This will then allow Spreedly to add the Stripe-Account header on calls to complete Stripe Connect requests.

Stripe Radar

Stripe Radar is a fraud detection tool that was created by Stripe. Radar is included with Stripe payment processing and uses a variety of signals to detect fraud. Per Stripe’s documentation:

As part of their role in payment processing, Stripe.js provides advanced fraud detection by looking at signals about both device characteristics and user activity indicators that help distinguish between legitimate and fraudulent transactions.

To use these advanced fraud detection signals through the Spreedly platform, the customer activity must be linked to a Radar Session ID that can be passed into the transaction. Spreedly provides a helper function in our iFrame library that helps customers obtain a Stripe Radar Session ID. To use this feature through Spreedly, you will need to write to Stripe support ([email protected]) and request for the Stripe Radar Sessions feature to be enabled.

Follow these instructions to obtain a Radar Session ID using Spreedly’s iFrame:

  1. Include the Stripe javascript library on your checkout page. To increase the effectiveness of Radar, add the Stripe javascript library to other pages of your website as well.
<script src="https://js.stripe.com/v3/"></script>
  1. Call the stripeRadar function from our iFrame helper to establish a Radar session and obtain the radar_session_id. This function takes three arguments:
  • Your Stripe publishable key available in the Stripe dashboard.
  • A callback function that will receive the radar_session_id. The stripeRadar function requires an API call to Stripe, so the callback function will be called asynchronously when the request completes.
  • An object with stripeAccount passed in (eg., { stripeAccount: ‘acct_24BFMpJ1svR5A89k’ }). This is only intended for users of Stripe Connect. If you’re not a user of Stripe Connect and/or don’t intend to use this object then skip on sending this parameter.
function callback(radar_session_id) {
  // pass radar_session_id to your backend to use it
  // as a gateway specific field when making an authorization
  // or purchase request
}

Spreedly.stripeRadar("publishableKey", callback, options)

The stripeRadar function can be called at any point on the checkout page.

  1. Pass the radar_session_id obtained in your callback during your authorization/purchase request as a gateway specific field radar_session_id.
curl https://core.spreedly.com/v1/gateways/T11bJAANtTWnxl36GYjKWvbNK0g/purchase.xml \
  -u ''C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
  -H 'Content-Type: application/xml' \
  -d '<transaction>
        <payment_method_token>1rpKvP8zOUhj4Y9EDrIoIYQzzD5</payment_method_token>
        <amount>100</amount>
        <currency_code>USD</currency_code>
        <gateway_specific_fields>
          <stripe_payment_intents>
            <radar_session_id>re_dfa3648ceeaf456a</radar_session_id>
          </stripe_payment_intents>
        </gateway_specific_fields>
      </transaction>'
  1. If you have enabled Stripe Radar through Stripe support and you want the ability to selectively disable Radar on a transaction-by-transaction basis, you may pass the skip_radar_rules GSF with a value of true (see example below). This will cause all Radar rules to be skipped for that transaction. Note that you may need to ask Stripe support ([email protected]) to enable the 'skip rules’ feature for your account.
curl https://core.spreedly.com/v1/gateways/T11bJAANtTWnxl36GYjKWvbNK0g/purchase.xml \
  -u ''C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
  -H 'Content-Type: application/xml' \
  -d '<transaction>
        <payment_method_token>1rpKvP8zOUhj4Y9EDrIoIYQzzD5</payment_method_token>
        <amount>100</amount>
        <currency_code>USD</currency_code>
        <gateway_specific_fields>
          <stripe_payment_intents>
            <skip_radar_rules>true</skip_radar_rules>
          </stripe_payment_intents>
        </gateway_specific_fields>
      </transaction>'

Stripe alternative payment methods

Spreedly supports purchases with alternative payment methods (APMs) by leveraging Stripe’s Payment Element framework. Please visit Stripe APM offsite payments for details.

Apple Pay and Google Pay

Spreedly supports sending billing address details to the Stripe Payment Intents gateway for transactions using Apple Pay and Google Pay. The billing_address field values from your request will be passed to Stripe when the card is tokenized.

See our Apple Payand Google Pay guides for more information on these digital wallet options.

Working with Stripe objects

Spreedly supports creating and updating several different types of Stripe objects (such as customers, payment_methods, and charges) that allow for native Stripe api calls if the functionality is not supported through Spreedly.

Below is an example of this with Stripe Smart Retry.

  1. Create a normal Stripe Payment Intents gateway with Spreedly.
  2. Tokenize payment method data with Spreedly.
  3. Call the store action on the Stripe Payment Intents gateway at Spreedly. This action will return a Spreedly third_party_token. See Third-party vaulting.
  4. The gateway_transaction_id field will be formatted customer_id | payment_method_id which corresponds to the Stripe customer and payment_method objects.
  5. Make calls to Stripe with the customer_id and payment_method_id.
curl https://core.spreedly.com/v1/gateways/gateway_token/store.xml \
  -u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
  -H 'Content-Type: application/xml' \
  -d '<transaction>
        <payment_method_token>your payment_method_token</payment_method_token>
      </transaction>'
<transaction>
    <created_at type="dateTime">2022-05-02T14:00:57Z</created_at>
    <currency_code nil="true"/>
    <updated_at type="dateTime">2022-05-02T14:00:59Z</updated_at>
    <succeeded type="boolean">true</succeeded>
    <token>aBIy8fEZVLkl24PUR4YsxmmOBWI</token>
    <state>succeeded</state>
    <gateway_specific_fields nil="true"/>
    <gateway_specific_response_fields>
        <stripe_payment_intents>
    </stripe_payment_intents>
    </gateway_specific_response_fields>
    <transaction_type>Store</transaction_type>
    <third_party_token nil="true"/>
    <gateway_transaction_id>cus_LcEGDKDNhCtYVi|pm_1Kuzo5AWOtgoysogAVxrr30l</gateway_transaction_id>
    <gateway_latency_ms type="integer">2131</gateway_latency_ms>
    <message key="messages.transaction_succeeded">Succeeded!</message>
    <gateway_token>WKZOUVVEqUv778Pfuw1e2buZSSz</gateway_token>
    <gateway_type>stripe_payment_intents</gateway_type>
    <payment_method>
        <token>OsDTu4loBTdFSTh53bcEPFCqTKf</token>
        <created_at type="dateTime">2022-05-02T14:00:59Z</created_at>
        <updated_at type="dateTime">2022-05-02T14:00:59Z</updated_at>
        <gateway_type>stripe_payment_intents</gateway_type>
        <storage_state>retained</storage_state>
        <metadata nil="true"/>
        <third_party_token>cus_LcEGDKDNhCtYVi|pm_1Kuzo5AWOtgoysogAVxrr30l</third_party_token>
        <payment_method_type>third_party_token</payment_method_type>
        <errors>
    </errors>
    </payment_method>
    <basis_payment_method>
        <token>RBn5Fa3SHIS0UtGlij8VnCNuUPD</token>
        <created_at type="dateTime">2022-04-14T20:13:42Z</created_at>
        <updated_at type="dateTime">2022-05-02T14:00:59Z</updated_at>
        <email>[email protected]</email>
        <data nil="true"/>
        <storage_state>retained</storage_state>
        <test type="boolean">false</test>
        <metadata>
            <key>string value</key>
            <another_key type="integer">123</another_key>
            <final_key type="boolean">true</final_key>
        </metadata>
        <callback_url nil="true"/>
        <last_four_digits>4242</last_four_digits>
        <first_six_digits>424242</first_six_digits>
        <card_type>visa</card_type>
        <first_name>Joe</first_name>
        <last_name>Jones</last_name>
        <month type="integer">1</month>
        <year type="integer">2029</year>
        <address1>33 Lane Road</address1>
        <address2>Apartment 4</address2>
        <city>Wanaque</city>
        <state>NJ</state>
        <zip>31331</zip>
        <country>US</country>
        <phone_number>919.331.3313</phone_number>
        <company>Acme Inc.</company>
        <full_name>Joe Jones</full_name>
        <eligible_for_card_updater type="boolean">true</eligible_for_card_updater>
        <shipping_address1>33 Lane Road</shipping_address1>
        <shipping_address2>Apartment 4</shipping_address2>
        <shipping_city>Wanaque</shipping_city>
        <shipping_state>NJ</shipping_state>
        <shipping_zip>31331</shipping_zip>
        <shipping_country>US</shipping_country>
        <shipping_phone_number>919.331.3313</shipping_phone_number>
        <issuer_identification_number>42424242</issuer_identification_number>
        <payment_method_type>credit_card</payment_method_type>
        <errors>
    </errors>
        <verification_value></verification_value>
        <number>XXXX-XXXX-XXXX-4242</number>
        <fingerprint>74eb9064510ce889cc145b3d58068a62cf3f</fingerprint>
    </basis_payment_method>
    <response>
        <success type="boolean">true</success>
        <message>Transaction approved</message>
        <avs_code nil="true"/>
        <avs_message nil="true"/>
        <cvv_code nil="true"/>
        <cvv_message nil="true"/>
        <pending type="boolean">false</pending>
        <result_unknown type="boolean">false</result_unknown>
        <error_code nil="true"/>
        <error_detail nil="true"/>
        <cancelled type="boolean">false</cancelled>
        <fraud_review nil="true"/>
        <created_at type="dateTime">2022-05-02T14:00:59Z</created_at>
        <updated_at type="dateTime">2022-05-02T14:00:59Z</updated_at>
    </response>
</transaction>

Adding a Stripe Payment Intents gateway for Setup Intents

If you would like to utilize the Setup Intent object when working with off_session transactions you need reach out to the Stripe support team and request that “Managing Transaction ID” be enabled for your account. Once ready to enable, simply include the transaction_id_management_enabled=true flag. The Setup Intent flow is used to authenticate a payment method for future usage but no charge is performed at the time of authentication.

curl https://core.spreedly.com/v1/gateways.xml \
  -u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
  -H 'Content-Type: application/xml' \
  -d '<gateway>
        <gateway_type>stripe_payment_intents</gateway_type>
        <login>your api secret key</login>
        <transaction_id_management_enabled>true</transaction_id_management_enabled>
      </gateway>'
<gateway>
  <token>WcbgK9EwSKrWJl5WnsstUj1BOM0</token>
  <gateway_type>stripe_payment_intents</gateway_type>
  <name>Stripe Payment Intents</name>
  <description nil="true"/>
  <merchant_profile_key nil="true"/>
  <sub_merchant_key nil="true"/>
  <characteristics>
    <supports_purchase type="boolean">true</supports_purchase>
    <supports_authorize type="boolean">true</supports_authorize>
    <supports_capture type="boolean">true</supports_capture>
    <supports_credit type="boolean">true</supports_credit>
    <supports_general_credit type="boolean">false</supports_general_credit>
    <supports_void type="boolean">true</supports_void>
    <supports_adjust type="boolean">false</supports_adjust>
    <supports_verify type="boolean">true</supports_verify>
    <supports_reference_purchase type="boolean">false</supports_reference_purchase>
    <supports_purchase_via_preauthorization type="boolean">false</supports_purchase_via_preauthorization>
    <supports_offsite_purchase type="boolean">true</supports_offsite_purchase>
    <supports_offsite_authorize type="boolean">false</supports_offsite_authorize>
    <supports_offsite_synchronous_purchase type="boolean">false</supports_offsite_synchronous_purchase>
    <supports_offsite_synchronous_authorize type="boolean">false</supports_offsite_synchronous_authorize>
    <supports_3dsecure_purchase type="boolean">true</supports_3dsecure_purchase>
    <supports_3dsecure_authorize type="boolean">true</supports_3dsecure_authorize>
    <supports_3dsecure_2_mpi_purchase type="boolean">false</supports_3dsecure_2_mpi_purchase>
    <supports_3dsecure_2_mpi_authorize type="boolean">false</supports_3dsecure_2_mpi_authorize>
    <supports_store type="boolean">true</supports_store>
    <supports_remove type="boolean">true</supports_remove>
    <supports_fraud_review type="boolean">false</supports_fraud_review>
    <supports_network_tokenization type="boolean">true</supports_network_tokenization>
    <supports_populate_mit_fields type="boolean">false</supports_populate_mit_fields>
    <supports_inquire_by_gateway_transaction_id type="boolean">false</supports_inquire_by_gateway_transaction_id>
    <supports_inquire_by_order_id type="boolean">false</supports_inquire_by_order_id>
    <supports_transaction_retry type="boolean">true</supports_transaction_retry>
    <supports_stored_stored_credentials type="boolean">false</supports_stored_stored_credentials>
    <supports_card_scheme_ntid type="boolean">true</supports_card_scheme_ntid>
    <supports_3dsecure_2_purchase type="boolean">true</supports_3dsecure_2_purchase>
    <supports_3dsecure_2_authorize type="boolean">true</supports_3dsecure_2_authorize>
    <supports_stored_credentials type="boolean">true</supports_stored_credentials>
  </characteristics>
  <credentials>
  </credentials>
  <gateway_settings>
    <webhook_id nil="true"/>
    <transaction_id_management_enabled>true</transaction_id_management_enabled>
  </gateway_settings>
  <gateway_specific_fields>
    <gateway_specific_field>receipt_email</gateway_specific_field>
    <gateway_specific_field>radar_session_id</gateway_specific_field>
    <gateway_specific_field>skip_radar_rules</gateway_specific_field>
    <gateway_specific_field>application_fee</gateway_specific_field>
    <gateway_specific_field>stripe_account</gateway_specific_field>
    <gateway_specific_field>metadata</gateway_specific_field>
    <gateway_specific_field>idempotency_key</gateway_specific_field>
    <gateway_specific_field>reason</gateway_specific_field>
    <gateway_specific_field>refund_application_fee</gateway_specific_field>
    <gateway_specific_field>refund_fee_amount</gateway_specific_field>
    <gateway_specific_field>reverse_transfer</gateway_specific_field>
    <gateway_specific_field>account_id</gateway_specific_field>
    <gateway_specific_field>customer_id</gateway_specific_field>
    <gateway_specific_field>validate</gateway_specific_field>
    <gateway_specific_field>make_default</gateway_specific_field>
    <gateway_specific_field>cancellation_reason</gateway_specific_field>
    <gateway_specific_field>capture_method</gateway_specific_field>
    <gateway_specific_field>confirm</gateway_specific_field>
    <gateway_specific_field>confirmation_method</gateway_specific_field>
    <gateway_specific_field>customer</gateway_specific_field>
    <gateway_specific_field>description</gateway_specific_field>
    <gateway_specific_field>moto</gateway_specific_field>
    <gateway_specific_field>off_session</gateway_specific_field>
    <gateway_specific_field>on_behalf_of</gateway_specific_field>
    <gateway_specific_field>payment_method_types</gateway_specific_field>
    <gateway_specific_field>return_email</gateway_specific_field>
    <gateway_specific_field>return_url</gateway_specific_field>
    <gateway_specific_field>save_payment_method</gateway_specific_field>
    <gateway_specific_field>setup_future_usage</gateway_specific_field>
    <gateway_specific_field>statement_descriptor</gateway_specific_field>
    <gateway_specific_field>statement_descriptor_suffix</gateway_specific_field>
    <gateway_specific_field>transfer_amount</gateway_specific_field>
    <gateway_specific_field>transfer_destination</gateway_specific_field>
    <gateway_specific_field>transfer_group</gateway_specific_field>
    <gateway_specific_field>application_fee_amount</gateway_specific_field>
    <gateway_specific_field>request_three_d_secure</gateway_specific_field>
    <gateway_specific_field>error_on_requires_action</gateway_specific_field>
    <gateway_specific_field>network_transaction_id</gateway_specific_field>
    <gateway_specific_field>claim_without_transaction_id</gateway_specific_field>
    <gateway_specific_field>fulfillment_date</gateway_specific_field>
    <gateway_specific_field>event_type</gateway_specific_field>
    <gateway_specific_field>modal_challenge</gateway_specific_field>
    <gateway_specific_field>idempotent_request</gateway_specific_field>
    <gateway_specific_field>merchant_reference</gateway_specific_field>
    <gateway_specific_field>customer_reference</gateway_specific_field>
    <gateway_specific_field>shipping_address_zip</gateway_specific_field>
    <gateway_specific_field>shipping_from_zip</gateway_specific_field>
    <gateway_specific_field>shipping_amount</gateway_specific_field>
    <gateway_specific_field>line_items</gateway_specific_field>
  </gateway_specific_fields>
  <payment_methods>
    <payment_method>credit_card</payment_method>
    <payment_method>third_party_token</payment_method>
    <payment_method>bank_account</payment_method>
    <payment_method>stripe_apm</payment_method>
    <payment_method>google_pay</payment_method>
    <payment_method>apple_pay</payment_method>
  </payment_methods>
  <state>retained</state>
  <redacted type="boolean">false</redacted>
  <sandbox type="boolean">false</sandbox>
  <mode>default</mode>
  <created_at type="dateTime">2023-09-13T21:16:12Z</created_at>
  <updated_at type="dateTime">2023-09-13T21:16:12Z</updated_at>
</gateway>

Off-session payments are possible for non-3DS and 3DS transactions. 3DS must run on every on-session transaction under SCA because Stripe will not be able to request exemptions for you.

Spreedly will utilize the Setup Intent API at Stripe if the transaction is a #verify or if the following conditions are met on an #authorization transaction.

  • transaction_id_management_enabled=true is enabled on the gateway at Spreedly
  • stored_credential_initiator=cardholder or setup_future_usage=off_session is sent in the transaction request to Spreedly.

Authorizations performed via the Setup Intent API are neither “capturable” with #capture nor “voidable” with #void and will fail if attempted.

To perform an MIT transaction on a payment method authenticated via a setup intent, make a #purchase call or #authorization call on the gateway with the payment_method_token that was authenticated. Be sure to include stored_credential_initiator=merchant or off_session=true to tell Spreedly you are doing a MIT transaction.

Off-session payments

Before you can run off-session #purchase transactions you need reach out to the Stripe support team and request that “Managing Transaction ID” be enabled for your account.

For Stripe Payment Intents, performing off session payments can be done using Spreedly’s first class support with the stored credential framework. Sending stored credential data is simple. For any Authorize or Purchase request, you need to include two fields which tell Spreedly a little bit more about the nature of the transaction:

  • stored_credential_initiator
  • stored_credential_reason_type

Off session payments can also be used via GSFs as described below This feature requires setting up the card first, by passing certain fields and values, i.e.:

Set up future usage with authorizations

  1. Create a payment method with the card.
  2. Call #authorize with setup_future_usage='off_session' as a gateway specific field.
    1. If 3DS is requested, an authentication flow may trigger and cardholder proceeds to complete it.
  3. Once the original authorization shows succeeded=true, no further #authorize calls are needed.
  4. Future #purchase transactions for that Payment Method, passing off_session=true succeed without requiring authentication.
    1. off_session=true indicates that the customer is not present during the payment attempt.

Set up future usage with purchases

  1. Create a payment method with the card.
  2. Call #purchase with setup_future_usage='off_session' as a gateway specific field.
    1. For 3DS flows:
      1. An authentication flow may trigger and cardholder proceeds to complete it.
      2. If the authentication is successful, funds will attempt to be captured by Spreedly in the same transaction.
    2. For non-3DS flows:
      1. Funds will attempt to be captured by Spreedly in the same transaction.
  3. Future #purchase transactions for that Payment Method, passing off_session=true as a gateway specific field will succeed without requiring authentication.
    1. off_session=true indicates that the customer is not present during the payment attempt.

Caveats

All #authorize and #purchase calls that use setup_future_usage='off_session' will always set confirm=true.

Idempotent Requests

To prevent duplicate transactions on Stripe Payment Intents it is highly encouraged to pass the gateway specific field idempotency_key. This must be a unique key and it can be up to 255 characters long.

If an idempotency_key is provided then Spreedly will add a suffix to it on four different endpoints in order to prevent collision. The first one is when creating a payment method and we suffix it with ‘-pm’. When capturing a Payment Intent we suffix it with ‘-capture’. When creating a customer with the suffix of ‘-customer’. Finally, attaching a Payment Method to a specific customer with the suffix of ‘-attach’.

For 3DS transactions, when idempotency_key is not provided by the customer then Spreedly will use the transaction token as the key.

Gateway specific 3DS transations

Spreedly supports 3DS on Stripe through the Payment Intents API. A 3DS2 transaction utilizes a redirect flow for customers by default to authorize their payment method before completing an authorization or purchase. A modal challenge can be requested by passing in the modal_challenge GSF with a value of true.

As you initiate a new 3DS transaction, Spreedly will automatically attempt to confirm the associated PaymentIntent on creation. Additionally, we set the capture_method to be manual, making a separate call to capture the funds once 3DS is successful (or bypassed), as long as your transaction is a purchase.

Stripe uses an asynchronous flow for processing 3DS transactions, relying upon callback notifications to communicate the payment intent’s stages. Due to the asynchronous nature of 3DS transactions on Stripe, there is no guarantee that a transaction is complete when a customer’s browser is redirected back to your site. You will need to continue to check the status of the transaction at Spreedly until it has completed.

To use Stripe 3DS on Spreedly, you must create a webhook endpoint at Stripe so that they can notify us about changes to a payment intent’s status. Create the webhook through your Stripe Dashboard under Developers > Webhooks or Developers > Workbench > Webhooks, or programmatically, with the following properties:

  • Endpoint URL: https://core.spreedly.com/stripe/webhooks
  • Events:
    • For regular payment intent flow: payment_intent.succeeded, payment_intent.payment_failed, and payment_intent.amount_capturable_updated
    • For Setup Intent flow: setup_intent.cancelled, setup_intent.created, setup_intent.requires_action, setup_intent.setup_failed, setup_intent.succeeded

Note

  • Gateways created in connect mode for direct merchants already have webhooks.
  • The events you enable on your dashboard should match the Stripe flow type of your transaction. If the correct events are not enabled then you will receive the following error message, “Enabled events for the provided webhook do not include the required 3DS events.”

After saving the webhook, you will need to obtain two properties for use in your Stripe gateway at Spreedly that are available by accessing the webhook detail page in Stripe’s dashboard.

The webhook_id can be found in your browser’s address bar and is the last segment of the URL. The Stripe webhook id begins with we_, for example: we_1EYfxCAWOtgoysog3lIoCESp. The webhook_signing_secret is located in the 'Signing Secret’ section of the webhook detail page. Spreedly uses these values to ensure we can receive notifications for changes to a payment intent’s status and to verify that events are sent by Stripe.

Once you have the webhook_id and webhook_signing_secret, you can create a gateway in the Spreedly API by passing them as parameters like so:

Spreedly supports gateway specific 3DS2 on verify transactions only for the Stripe Payment Intents gateway. When the standard gateway specific 3DS parameters are passed on a verify with this gateway, Spreedly will perform a setup intent with the necessary 3DS transaction flagging.

curl https://core.spreedly.com/v1/gateways.xml \
  -u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
  -H 'Content-Type: application/xml' \
  -d '<gateway>
        <gateway_type>stripe_payment_intents</gateway_type>
        <login>your api secret key</login>
        <webhook_id>your webhook id</webhook_id>
        <webhook_signing_secret>your webhook signing secret</webhook_signing_secret>
      </gateway>'
<gateway>
  <token>ErnO5Fl3ufxQlWisIHJK1xnFXRC</token>
  <gateway_type>stripe_payment_intents</gateway_type>
  <name>Stripe Payment Intents</name>
  <description nil="true"/>
  <merchant_profile_key nil="true"/>
  <sub_merchant_key nil="true"/>
  <characteristics>
    <supports_purchase type="boolean">true</supports_purchase>
    <supports_authorize type="boolean">true</supports_authorize>
    <supports_capture type="boolean">true</supports_capture>
    <supports_credit type="boolean">true</supports_credit>
    <supports_general_credit type="boolean">false</supports_general_credit>
    <supports_void type="boolean">true</supports_void>
    <supports_adjust type="boolean">false</supports_adjust>
    <supports_verify type="boolean">true</supports_verify>
    <supports_reference_purchase type="boolean">false</supports_reference_purchase>
    <supports_purchase_via_preauthorization type="boolean">false</supports_purchase_via_preauthorization>
    <supports_offsite_purchase type="boolean">true</supports_offsite_purchase>
    <supports_offsite_authorize type="boolean">false</supports_offsite_authorize>
    <supports_offsite_synchronous_purchase type="boolean">false</supports_offsite_synchronous_purchase>
    <supports_offsite_synchronous_authorize type="boolean">false</supports_offsite_synchronous_authorize>
    <supports_3dsecure_purchase type="boolean">true</supports_3dsecure_purchase>
    <supports_3dsecure_authorize type="boolean">true</supports_3dsecure_authorize>
    <supports_3dsecure_2_mpi_purchase type="boolean">false</supports_3dsecure_2_mpi_purchase>
    <supports_3dsecure_2_mpi_authorize type="boolean">false</supports_3dsecure_2_mpi_authorize>
    <supports_store type="boolean">true</supports_store>
    <supports_remove type="boolean">true</supports_remove>
    <supports_fraud_review type="boolean">false</supports_fraud_review>
    <supports_network_tokenization type="boolean">true</supports_network_tokenization>
    <supports_populate_mit_fields type="boolean">false</supports_populate_mit_fields>
    <supports_inquire_by_gateway_transaction_id type="boolean">false</supports_inquire_by_gateway_transaction_id>
    <supports_inquire_by_order_id type="boolean">false</supports_inquire_by_order_id>
    <supports_transaction_retry type="boolean">true</supports_transaction_retry>
    <supports_stored_stored_credentials type="boolean">false</supports_stored_stored_credentials>
    <supports_card_scheme_ntid type="boolean">true</supports_card_scheme_ntid>
    <supports_3dsecure_2_purchase type="boolean">true</supports_3dsecure_2_purchase>
    <supports_3dsecure_2_authorize type="boolean">true</supports_3dsecure_2_authorize>
    <supports_stored_credentials type="boolean">true</supports_stored_credentials>
  </characteristics>
  <credentials>
  </credentials>
  <gateway_settings>
    <webhook_id>your webhook id</webhook_id>
    <transaction_id_management_enabled>false</transaction_id_management_enabled>
  </gateway_settings>
  <gateway_specific_fields>
    <gateway_specific_field>receipt_email</gateway_specific_field>
    <gateway_specific_field>radar_session_id</gateway_specific_field>
    <gateway_specific_field>skip_radar_rules</gateway_specific_field>
    <gateway_specific_field>application_fee</gateway_specific_field>
    <gateway_specific_field>stripe_account</gateway_specific_field>
    <gateway_specific_field>metadata</gateway_specific_field>
    <gateway_specific_field>idempotency_key</gateway_specific_field>
    <gateway_specific_field>reason</gateway_specific_field>
    <gateway_specific_field>refund_application_fee</gateway_specific_field>
    <gateway_specific_field>refund_fee_amount</gateway_specific_field>
    <gateway_specific_field>reverse_transfer</gateway_specific_field>
    <gateway_specific_field>account_id</gateway_specific_field>
    <gateway_specific_field>customer_id</gateway_specific_field>
    <gateway_specific_field>validate</gateway_specific_field>
    <gateway_specific_field>make_default</gateway_specific_field>
    <gateway_specific_field>cancellation_reason</gateway_specific_field>
    <gateway_specific_field>capture_method</gateway_specific_field>
    <gateway_specific_field>confirm</gateway_specific_field>
    <gateway_specific_field>confirmation_method</gateway_specific_field>
    <gateway_specific_field>customer</gateway_specific_field>
    <gateway_specific_field>description</gateway_specific_field>
    <gateway_specific_field>moto</gateway_specific_field>
    <gateway_specific_field>off_session</gateway_specific_field>
    <gateway_specific_field>on_behalf_of</gateway_specific_field>
    <gateway_specific_field>payment_method_types</gateway_specific_field>
    <gateway_specific_field>return_email</gateway_specific_field>
    <gateway_specific_field>return_url</gateway_specific_field>
    <gateway_specific_field>save_payment_method</gateway_specific_field>
    <gateway_specific_field>setup_future_usage</gateway_specific_field>
    <gateway_specific_field>statement_descriptor</gateway_specific_field>
    <gateway_specific_field>statement_descriptor_suffix</gateway_specific_field>
    <gateway_specific_field>transfer_amount</gateway_specific_field>
    <gateway_specific_field>transfer_destination</gateway_specific_field>
    <gateway_specific_field>transfer_group</gateway_specific_field>
    <gateway_specific_field>application_fee_amount</gateway_specific_field>
    <gateway_specific_field>request_three_d_secure</gateway_specific_field>
    <gateway_specific_field>error_on_requires_action</gateway_specific_field>
    <gateway_specific_field>network_transaction_id</gateway_specific_field>
    <gateway_specific_field>claim_without_transaction_id</gateway_specific_field>
    <gateway_specific_field>fulfillment_date</gateway_specific_field>
    <gateway_specific_field>event_type</gateway_specific_field>
    <gateway_specific_field>modal_challenge</gateway_specific_field>
    <gateway_specific_field>idempotent_request</gateway_specific_field>
    <gateway_specific_field>merchant_reference</gateway_specific_field>
    <gateway_specific_field>customer_reference</gateway_specific_field>
    <gateway_specific_field>shipping_address_zip</gateway_specific_field>
    <gateway_specific_field>shipping_from_zip</gateway_specific_field>
    <gateway_specific_field>shipping_amount</gateway_specific_field>
    <gateway_specific_field>line_items</gateway_specific_field>
  </gateway_specific_fields>
  <payment_methods>
    <payment_method>credit_card</payment_method>
    <payment_method>third_party_token</payment_method>
    <payment_method>bank_account</payment_method>
    <payment_method>stripe_apm</payment_method>
    <payment_method>google_pay</payment_method>
    <payment_method>apple_pay</payment_method>
  </payment_methods>
  <state>retained</state>
  <redacted type="boolean">false</redacted>
  <sandbox type="boolean">false</sandbox>
  <mode>default</mode>
  <created_at type="dateTime">2023-09-13T21:17:41Z</created_at>
  <updated_at type="dateTime">2023-09-13T21:17:41Z</updated_at>
</gateway>

Third-party 3DS2 auth data

Spreedly will automatically handle the field mapping for sending 3DS2 authentication data to Stripe. For more information about how to use this feature, see Spreedly 3DS Solutions. Spreedly fields map to the relevant Stripe fields as described in the following table. Please see Stripe Payment Intents documentation for detailed descriptions of each of these fields.

Spreedly fieldStripe field
authentication_valuecryptogram
directory_server_transaction_idtransaction_id
ecommerce_indicatorelectronic_commerce_indicator
versionversion

Gateway specific fields

Gateway specific fields, particularly when attempting 3D Secure transactions, are highlighted below:

  • return_url
  • setup_future_usage
  • off_session
  • customer
  • transfer_destination
  • transfer_group
  • transfer_amount
  • description
  • confirm
  • statement_descriptor
  • statement_descriptor_suffix
  • on_behalf_of
  • application_fee_amount
  • idempotency_key
  • request_three_d_secure
  • error_on_requires_action
  • network_transaction_id
  • claim_without_transaction_id
  • radar_session_id
  • skip_radar_rules
  • event_type
  • fulfillment_date
  • modal_challenge
  • idempotent_request
  • merchant_reference
  • customer_reference
  • shipping_address_zip
  • shipping_from_zip
  • shipping_amount
  • line_items
  • card_brand

If the customer is directly in the checkout flow and may need to authenticate their payment method, be sure to include a return_url. This is the url the customer will be redirected to following authentication.

For setup_future_usage and off_session please refer to the Off-session payments section above.

If a customer already exists for a payment method, you can pass the customer id in the customer field. When this is used, any payment methods used with the intent can only be attached to the customer provided, and payment methods that have been attached to another customer can’t be used with the current payment intent.

The transfer_destination, transfer_group, transfer_amount, on_behalf_of, and application_fee_amount fields may be set if you want to create charges on behalf of connected accounts. For more information about charging connected accounts using payment intents, see here. transfer_amount and application_fee_amount are mutually exclusive; when using this feature, only set one of them in your request.

The statement_descriptor and statement_descriptor_suffix fields are ways to set the string that is displayed on your customer’s credit card statement. See the Stripe documentation on statement descriptors for more information.

The idempotency_key is for safely retrying requests without accidentally performing the same operation twice. Spreedly currently supports this field for synchronous transactions only; 3DS and Stripe APMs are not considered synchronous transactions.

In order to successfully use the idempotency_key feature, the following conditions must be met to ensure we send identical requests to Stripe PI:

  • The gateway specific field idempotent_request must be set to true
  • An order_id must be specified in the top level of transaction request
  • The presence or absence of CVV must be consistent

The network_transaction_id is used to send a previously existing network transaction id for the payment method in use.

The claim_without_transaction_id field is set to true in an #authorize or #purchase transaction when that transaction does not provide a transaction id. The gateway must have transaction_id_management_enabled set to true, indicating that gateway’s account has been approved to use Stripe’s “Managing Transaction ID” feature. For more information, see Stripe’s documentation on previous authorization agreements here.

If you wish to request 3D Secure manually, instead of relying on Stripe’s SCA engine, use the request_three_d_secure field to specify this. The two accepted values are 'any’ and 'automatic’. If this field is not included in your request, it defaults to 'automatic’. See Stripe’s documentation for more information on how to use request_three_d_secure.

Payment Intents must be confirmed before they can be used. When initiating Spreedly’s solution for Stripe Payment Intents, we will automatically confirm the intent in order to kick off and proceed through the intended action. However, if you desire to confirm the payment intent on your end, set the confirm field to false.

Only set confirm to false if you are prepared to manually confirm the intent yourself; when false, Spreedly will create a new payment intent, but halt any other processing of the payment intent. You may retrieve the Payment Intent’s id from the transaction’s gateway_transaction_id to proceed directly with Stripe.

If you are using setup_future_usage in your #authorize calls, confirm is not overrideable. Please refer to the Off-session section above for details.

If you wish the payment attempt fails if the payment intent transitions into 3D Secure flow, set the gateway specific field error_on_requires_action to true. See Stripe’s documentation for more information on how to use error_on_requires_action.

See the above section Stripe Radar for usage of the radar_session_id and skip_radar_rules fields.

The fulfillment_date field accepts a Unix timestamp. Before using this field you must have this feature enabled on your Stripe account, which you can request by reaching out to the Stripe support team.

The modal_challenge field accepts a boolean value. By setting it to true Spreedly Lifecycle will attempt to render any 3DS challenges in a modal rather than redirect.

Requests to Stripe Payment Intents may include several additional pieces of data to qualify for Level 2 or Level 3 rates. These include merchant_reference, customer_reference, shipping_address_zip, shipping_from_zip, shipping_amount, and line_items.

  • merchant_reference - An alphanumeric string of up to 25 characters in length. This unique value is assigned by the merchant to identify the order. Also known as an “Order ID”.
  • customer_reference - An alphanumeric string of up to 17 characters in length. Customers sometimes are required to supply this; see further discussion below.
  • shipping_address_zip - The customer’s U.S. shipping ZIP code.
  • shipping_from_zip - The merchant’s U.S. shipping ZIP code.
  • shipping_amount - The shipping cost, in cents, as a non-negative integer.
  • line_items - (Array of objects. One object per type of item. Maximum of 200 line items allowed.)
    • product_code: Up to 12 characters that uniquely identify the product.
    • product_description: Up to 26 alphanumeric characters long describing the product.
    • unit_cost: Cost of the product, in cents, as a positive integer greater than 0.
    • quantity: The number of items of this type sold, as a positive integer greater than 0.
    • tax_amount: The amount of tax this item had added to it, in cents, as a non-negative integer
    • discount_amount: The amount an item was discounted—if there was a sale, for example, as a non-negative integer.

You can achieve Level 3 rates by sending merchant_reference, customer_reference, shipping_address_zip, shipping_from_zip, shipping_amount, and a full list of line_items. However, if you can’t provided a full list of line_items you can still receive Level 2 rates by providing a single summary-level line item.

You can set co-badged cards (for example, cards branded with both Visa and Mastercard and a local scheme such as Cartes Bancaires) by using the card_brand field. Please visit Card brand choice for more information.

curl https://core.spreedly.com/v1/gateways/LlkjmEk0xNkcWrNixXa1fvNoTP4/purchase.xml \
  -u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
  -H 'Content-Type: application/xml' \
  -d '<transaction>
        <payment_method_token>56wyNnSmuA6CWYP7w0MiYCVIbW6</payment_method_token>
        <amount>100</amount>
        <currency_code>USD</currency_code>
        <gateway_specific_fields>
          <stripe_payment_intents>
            <receipt_email>[email protected]</receipt_email>
            <return_email>[email protected]</return_email>
            <return_url>http://www.example.com/redirect</return_url>
            <description>Description of transaction</description>
            <metadata>
              <hat_type>Fedora</hat_type>
              <cat_name>Waffles</cat_name>
            </metadata>
            <capture_method>manual</capture_method>
            <cancellation_reason>duplicate</cancellation_reason>
            <confirm>true</confirm>
            <confirmation_method>manual</confirmation_method>
            <moto>true</moto>
            <payment_method_types>card</payment_method_types>
            <save_payment_method>true</save_payment_method>
            <customer>cus_3sgheFxeBgTQ8m</customer>
            <setup_future_usage>off_session</setup_future_usage>
            <off_session>false</off_session>
            <statement_descriptor>5K Race Ticket</statement_descriptor>
            <statement_descriptor_suffix>ORDER 10108</statement_descriptor_suffix>
            <transfer_destination>acct_123456789</transfer_destination>
            <transfer_group>ORDER10</transfer_group>
            <transfer_amount>100</transfer_amount>
            <on_behalf_of>acct_123456789</on_behalf_of>
            <application_fee_amount>100</application_fee_amount>
            <application_fee>100</application_fee>
            <idempotency_key>idempotency_key</idempotency_key>
            <request_three_d_secure>automatic</request_three_d_secure>
            <error_on_requires_action>false</error_on_requires_action>
            <network_transaction_id>111111111</network_transaction_id>
            <claim_without_transaction_id>false</claim_without_transaction_id>
            <event_type>your event type</event_type>
            <fulfillment_date>1637103715</fulfillment_date>
            <radar_session_id>re_dfa3648ceeaf456a</radar_session_id>
            <skip_radar_rules>true</skip_radar_rules>
            <stripe_account>123456789</stripe_account>
            <card_brand>cartes_bancaires</card_brand>
          </stripe_payment_intents>
        </gateway_specific_fields>
      </transaction>'
<transaction>
  <on_test_gateway type="boolean">true</on_test_gateway>
  <created_at type="dateTime">2023-09-13T21:13:02Z</created_at>
  <updated_at type="dateTime">2023-09-13T21:13:02Z</updated_at>
  <succeeded type="boolean">true</succeeded>
  <state>succeeded</state>
  <token>Dg5pqmDbtOzUjke7tVMLEA1vgK9</token>
  <transaction_type>Purchase</transaction_type>
  <order_id nil="true"/>
  <ip nil="true"/>
  <description nil="true"/>
  <email nil="true"/>
  <merchant_name_descriptor nil="true"/>
  <merchant_location_descriptor nil="true"/>
  <merchant_profile_key nil="true"/>
  <gateway_specific_fields>
    <stripe_payment_intents>
      <receipt_email>[email protected]</receipt_email>
      <return_email>[email protected]</return_email>
      <return_url>http://www.example.com/redirect</return_url>
      <description>Description of transaction</description>
      <metadata>
        <hat_type>Fedora</hat_type>
        <cat_name>Waffles</cat_name>
      </metadata>
      <capture_method>manual</capture_method>
      <cancellation_reason>duplicate</cancellation_reason>
      <confirm>true</confirm>
      <confirmation_method>manual</confirmation_method>
      <moto>true</moto>
      <payment_method_types>card</payment_method_types>
      <save_payment_method>true</save_payment_method>
      <customer>cus_3sgheFxeBgTQ8m</customer>
      <setup_future_usage>off_session</setup_future_usage>
      <off_session>false</off_session>
      <statement_descriptor>5K Race Ticket</statement_descriptor>
      <statement_descriptor_suffix>ORDER 10108</statement_descriptor_suffix>
      <transfer_destination>acct_123456789</transfer_destination>
      <transfer_group>ORDER10</transfer_group>
      <transfer_amount>100</transfer_amount>
      <on_behalf_of>acct_123456789</on_behalf_of>
      <application_fee_amount>100</application_fee_amount>
      <application_fee>100</application_fee>
      <idempotency_key>idempotency_key</idempotency_key>
      <request_three_d_secure>automatic</request_three_d_secure>
      <error_on_requires_action>false</error_on_requires_action>
      <network_transaction_id>111111111</network_transaction_id>
      <claim_without_transaction_id>false</claim_without_transaction_id>
      <event_type>your event type</event_type>
      <fulfillment_date>1637103715</fulfillment_date>
      <radar_session_id>re_dfa3648ceeaf456a</radar_session_id>
      <skip_radar_rules>true</skip_radar_rules>
      <stripe_account>123456789</stripe_account>
    </stripe_payment_intents>
  </gateway_specific_fields>
  <gateway_specific_response_fields>
  </gateway_specific_response_fields>
  <gateway_transaction_id>46</gateway_transaction_id>
  <sub_merchant_key nil="true"/>
  <gateway_latency_ms type="integer">1</gateway_latency_ms>
  <warning nil="true"/>
  <application_id nil="true"/>
  <amount type="integer">100</amount>
  <local_amount nil="true"/>
  <currency_code>USD</currency_code>
  <retain_on_success type="boolean">false</retain_on_success>
  <payment_method_added type="boolean">false</payment_method_added>
  <smart_routed type="boolean">false</smart_routed>
  <stored_credential_initiator nil="true"/>
  <stored_credential_reason_type nil="true"/>
  <stored_credential_alternate_gateway nil="true"/>
  <populate_mit_fields type="boolean">false</populate_mit_fields>
  <message key="messages.transaction_succeeded">Succeeded!</message>
  <gateway_token>T11bJAANtTWnxl36GYjKWvbNK0g</gateway_token>
  <gateway_type>test</gateway_type>
  <shipping_address>
    <name>Newfirst Newlast</name>
    <address1 nil="true"/>
    <address2 nil="true"/>
    <city nil="true"/>
    <state nil="true"/>
    <zip nil="true"/>
    <country nil="true"/>
    <phone_number nil="true"/>
  </shipping_address>
  <response>
    <success type="boolean">true</success>
    <message>Successful purchase</message>
    <avs_code nil="true"/>
    <avs_message nil="true"/>
    <cvv_code nil="true"/>
    <cvv_message nil="true"/>
    <pending type="boolean">false</pending>
    <result_unknown type="boolean">false</result_unknown>
    <error_code nil="true"/>
    <error_detail nil="true"/>
    <cancelled type="boolean">false</cancelled>
    <fraud_review nil="true"/>
    <created_at type="dateTime">2023-09-13T21:13:02Z</created_at>
    <updated_at type="dateTime">2023-09-13T21:13:02Z</updated_at>
  </response>
  <api_urls>
  </api_urls>
  <payment_method>
    <token>1rpKvP8zOUhj4Y9EDrIoIYQzzD5</token>
    <created_at type="dateTime">2017-06-26T17:04:38Z</created_at>
    <updated_at type="dateTime">2023-09-07T18:17:19Z</updated_at>
    <email>[email protected]</email>
    <data>
      <my_payment_method_identifier>448</my_payment_method_identifier>
      <extra_stuff>
        <some_other_things>Can be anything really</some_other_things>
      </extra_stuff>
    </data>
    <storage_state>retained</storage_state>
    <test type="boolean">true</test>
    <metadata>
      <key>string value</key>
    </metadata>
    <callback_url nil="true"/>
    <last_four_digits>1111</last_four_digits>
    <first_six_digits>411111</first_six_digits>
    <card_type>visa</card_type>
    <first_name>Newfirst</first_name>
    <last_name>Newlast</last_name>
    <month type="integer">3</month>
    <year type="integer">2032</year>
    <address1 nil="true"/>
    <address2 nil="true"/>
    <city nil="true"/>
    <state nil="true"/>
    <zip nil="true"/>
    <country nil="true"/>
    <phone_number nil="true"/>
    <company nil="true"/>
    <full_name>Newfirst Newlast</full_name>
    <eligible_for_card_updater type="boolean">true</eligible_for_card_updater>
    <shipping_address1 nil="true"/>
    <shipping_address2 nil="true"/>
    <shipping_city nil="true"/>
    <shipping_state nil="true"/>
    <shipping_zip nil="true"/>
    <shipping_country nil="true"/>
    <shipping_phone_number nil="true"/>
    <issuer_identification_number nil="true"/>
    <click_to_pay type="boolean">false</click_to_pay>
    <managed nil="true"/>
    <payment_method_type>credit_card</payment_method_type>
    <stored_credential_usage>
      <test>
        <original_network_transaction_id>37be5367d6dbe4a88c9d</original_network_transaction_id>
        <network_transaction_id>37be5367d6dbe4a88c9d</network_transaction_id>
      </test>
    </stored_credential_usage>
    <errors>
    </errors>
    <verification_value></verification_value>
    <number>XXXX-XXXX-XXXX-1111</number>
    <fingerprint>e3cef43464fc832f6e04f187df25af497994</fingerprint>
  </payment_method>
  <attempt_3dsecure type="boolean">false</attempt_3dsecure>
</transaction>

3DS exemptions

A number of exemptions, including transaction risk analysis and low value requests, are covered automatically by Stripe Radar. As long as your account has access to this service, you do not need to take any further action to take advantage of these exemptions. Contact Stripe if you have any questions about this feature, or need to add it to your account.

Other exemptions that require additional fields are listed below:

MOTO

In order to mark any payments as MOTO, set the gateway specific field moto to true. You must contact Stripe to enable this feature on your account. MOTO transactions are considered cardholder initiated and if you intend to use this as the initial CIT to set up future transactions be sure to pass stored_credential_initiator: cardholder.

MIT

To set up recurring transactions that have the best success of bypassing 3DS authentication, set the value of setup_future_usage to off_session on the initial transaction or stored_credential_initiator: cardholder. This will allow the customer to authenticate once, and then indicates that you plan to use the card in subsequent, off-session transactions where the customer isn’t present.

In subsequent transactions using a payment method that’s been setup for future usage, set the gateway specific field off_session to true or stored_credential_initiator: merchant. Additionally, if you saved the payment method before September 14, 2019, Stripe will attempt to grandfather the payment method in.

Gateway specific response fields

Responses from the Stripe Payment Intents gateway may contain a number of response fields:

  • decline_code
  • outcome_network_status
  • outcome_reason
  • outcome_risk_level
  • outcome_seller_message
  • outcome_type
  • outcome_network_advice_code
  • outcome_network_decline_code
  • data_id
  • data_balance_transaction
  • data_balance_transaction_id
  • webhook_id
  • three_ds_authenticated
  • three_ds_version
  • three_ds_authentication_flow
  • card_funding
  • customer_id
  • bank_account_id
  • three_ds_result
  • three_ds_result_reason
  • network_transaction_id
  • authorization_code
  • address_line1_check
  • address_postal_code_check
  • cvc_check
  • network
  • issuer_country_code
  • stripe_payment_method_token
  • network_token - If applicable, an object that can contain multiple fields related to network tokenization at Stripe. Including but not limited to:
    • used - Indicates if the gateway used a network token provisioned at Stripe for the transaction vs the PAN.
  • stripe_should_retry
  • idempotent_replayed

To request any gateway_specific_fields or gateway_specific_response_fields, please contact Support with your request and the gateway documentation for the fields of interest.

Network tokenization

While our Network tokenization framework provisions network tokens here at Spreedly, in order to use our framework with a Stripe Payment Intents gateway, your Stripe account must be correctly configured. This will allow Spreedly to pass our provisioned network tokens to Stripe on your behalf.

Please contact Stripe support to configure your Stripe account for network tokenization.