Stored Credentials

Major card networks require that merchants include additional data values in their purchase and authorization requests to identify the storage and use of payment credentials. According to the card networks, merchants utilizing the stored credentials framework should see an improvement in approval rates especially for recurring and subscription based charges.

In continuing to provide a consistent interface to payment gateways, Spreedly provides first class support for sending stored credential data to a select number of gateways. Adding a bit of additional data to your transaction will enable Spreedly to generate the appropriate payment gateway request taking into account both the state of the payment method you are using and the additional data you are sending. Furthermore Spreedly handles storing and sending card network specific information allowing payment methods to be seamlessly used between different gateways while still providing the appropriate mapping of stored credential fields.

The flow advised by Mastercard and Visa when attempting to complete a flow with stored credentials is to first complete a Cardholder Initiated Transaction(CIT). This is where a cardholder authorizes the transaction and authenticates if needed. The card scheme will then return a network transaction id that references the agreement made between the cardholder’s payment method and the merchant. For a follow up Merchant Initiated Transaction(MIT), the network transaction id from the initial CIT should be sent to let the issuer know that this payment method has been successfully used in this agreement before.

The enforcement of strong customer authentication(SCA) in the EEA has made Stored Credentials even more pertinent when it comes to improving success rates. MITs are out of scope of SCA and therefore 3DS does not need to be requested on MITs that have were previously authenticated during the CIT. Since transactions cannot be challenged when out of scope, utilizing the stored credentials framework will let the issuing bank know that the transaction is merchant initiated, and will link back to the original CIT that was authenticated.

You can read more about stored credentials in this document provided by Visa.

Supported Gateways

Sending Stored Credential data

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

Both fields are required for Spreedly to populate requests to your payment gateway with the necessary stored credential fields. If only one of the fields is sent Spreedly will continue with the transaction but skip adding any stored credential data. Additionally, the two fields have a subset of values that are accepted.

stored_credential_initiator - merchant or cardholder

If the cardholder is present on the merchant’s checkout page and you are intending to set this payment method up for future usage where the cardholder is not present then pass in cardholder. If this is a merchant initiated transaction where the cardholder is not present and you want Spreedly to send the network transaction id then pass in merchant.

stored_credential_reason_type - recurring or unscheduled or installment
Spreedly will map the stored_credential_reason_type to what the gateway wants. In general a recurring transaction is considered on a fixed timeline with a fixed amount, an unscheduled transaction is not on a fixed timeline or fixed amount, and an installment transaction is not on a fixed amount but is on a fixed timeline.

You should use the combination of those two field values to properly identify the type of transaction you are sending. For example, if your transaction is for a regular monthly subscription and is charged the same time at a set interval (such as monthly) you would send a combination of "merchant" and "recurring". Or, if your customer is purchasing something on your website as a one time purchase but you are storing their payment details for future use, you would send "cardholder" and "unscheduled".

$ curl https://core.spreedly.com/v1/gateways/LlkjmEk0xNkcWrNixXa1fvNoTP4/purchase.json \
  -u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
  -H 'Content-Type: application/json' \
  -d '{
        "transaction": {
          "payment_method_token": "56wyNnSmuA6CWYP7w0MiYCVIbW6",
          "amount": 100,
          "currency_code": "USD",
          "stored_credential_initiator": "cardholder",
          "stored_credential_reason_type": "unscheduled"
        }
      }'
$ 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>
        <stored_credential_initiator>cardholder</stored_credential_initiator>
        <stored_credential_reason_type>unscheduled</stored_credential_reason_type>
      </transaction>'

To see how Spreedly used the stored credential fields you submitted along with the payment method used to generate the request to the gateway, you can use the transcript request to view the communication between Spreedly and your payment gateway. You may need to match it against the gateway docs to see that gateway’s specific stored credential fields.

Stored Credential Alternate Gateway

Spreedly provides the "stored_credential_alternate_gateway" field to better enable cross-gateway MIT transactions. This field accepts a String containing a specific gateway type or "scheme_issued". Gateways that provide the Network Transaction ID (NTID) directly from the network, called "Credit Card Provider Direct", are eligible to use this feature. When this field is passed on a transaction with a valid value, Spreedly will use a previously stored NTID from the alternate gateway for the transaction. Spreedly will determine sending the original or the most recent NTID, based on the requirements of the gateway. The alternate gateway credential will only be used if there is no stored credential for the transacting gateway and if both the alternate gateway and the transacting gateway have eligible Credit Card Provider Direct identifiers.

For example, consider a scenario where a merchant is integrated with both Adyen and CyberSource gateways. A payment method is used in an initial transaction on Adyen and a network transaction ID is returned and stored by Spreedly. For subsequent transactions using the same payment method on CyberSource, "adyen" can be passed in the stored credential alternate gateway field and the original network transaction ID (NTID) returned from Adyen will be passed along to CyberSource. This stored credential alternate gateway field could be useful when shifting recurring subscription payments from one gateway to another.

To use this field pass in the stored_credential_alternate_gateway field on any authorize or purchase request with the String of a gateway_type

$ curl https://core.spreedly.com/v1/gateways/LlkjmEk0xNkcWrNixXa1fvNoTP4/purchase.json \
  -u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
  -H 'Content-Type: application/json' \
  -d '{
        "transaction": {
          "payment_method_token": "56wyNnSmuA6CWYP7w0MiYCVIbW6",
          "amount": 100,
          "currency_code": "USD",
          "stored_credential_initiator": "cardholder",
          "stored_credential_reason_type": "unscheduled",
          "stored_credential_alternate_gateway": "adyen"
        }
      }'
$ 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>
        <stored_credential_initiator>cardholder</stored_credential_initiator>
        <stored_credential_reason_type>unscheduled</stored_credential_reason_type>
				<stored_credential_alternate_gateway>adyen</stored_credential_reason_type>
      </transaction>'

The following gateways are available to be used as alternate gateways:

Populate merchant initiated transactions fields

Supported gateways:

If you want to request Merchant Initiated Transactions (MIT), you are still able to do so using the above stored credential fields, however, Spreedly has a feature that can be used concurrently with the above fields in order to take away the burden of mapping additional MIT gateway specific fields. Often times gateways require the stored credential fields to be sent along with additional GSFs, using the populate MIT GSFs functionality takes away the extra mapping required on the gateway side to mark a transaction as merchant initiated.

When you provide populate_mit_fields=true, Spreedly includes the gateway specific fields (GSFs) required to identify the transaction as a Merchant Initiated Transaction (MIT) on your behalf. The first transaction is required to be Customer Initiated Transaction (CIT) in order to enable subsequent MIT transactions.

In many cases, gateways require GSFs to be sent in during a purchase or authorize in order to note that the transaction is a MIT and therefore out of scope of SCA. Managing the different gateway specific rules/fields in addition to stored credentials can be cumbersome, especially for merchants that perform MIT on multiple gateways.

Note: We recommend not sending these GSFs when populate_mit_fields=true, as they are always overwritten for MIT

Setup using CIT

$ curl https://core.spreedly.com/v1/gateways/LlkjmEk0xNkcWrNixXa1fvNoTP4/purchase.json \
  -u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
  -H 'Content-Type: application/json' \
  -d '{
        "transaction": {
          "payment_method_token": "56wyNnSmuA6CWYP7w0MiYCVIbW6",
          "amount": 100,
          "currency_code": "USD",
          "stored_credential_initiator": "cardholder",
          "stored_credential_reason_type": "recurring",
          "populate_mit_fields": "true"
        }
      }'
$ 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>
        <stored_credential_initiator>cardholder</stored_credential_initiator>
        <stored_credential_reason_type>recurring</stored_credential_reason_type>
        <populate_mit_fields>true</populate_mit_fields>
      </transaction>'

Subsequent MIT Transactions

$ curl https://core.spreedly.com/v1/gateways/LlkjmEk0xNkcWrNixXa1fvNoTP4/purchase.json \
  -u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
  -H 'Content-Type: application/json' \
  -d '{
        "transaction": {
          "payment_method_token": "56wyNnSmuA6CWYP7w0MiYCVIbW6",
          "amount": 100,
          "currency_code": "USD",
          "stored_credential_initiator": "merchant",
          "stored_credential_reason_type": "recurring",
          "populate_mit_fields": "true"
        }
      }'
$ 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>
        <stored_credential_initiator>merchant</stored_credential_initiator>
        <stored_credential_reason_type>recurring</stored_credential_reason_type>
        <populate_mit_fields>true</populate_mit_fields>
      </transaction>'

When you set populate_mit_fields to false or omit it, stored credentials work as usual and you must send in any GSFs that the gateway requires to properly identify the transaction as MIT.

Interim network transaction id's

There are several instances where a Network Transaction ID will become invalid. Those instances include but are not limited to the following:

  1. Acquirer Swap: The merchant switched acquirer / gateway for the processing of the MIT.
  2. Card Brand Swap: The merchant received an updated credential from an Account Updater service to replace the previous credential for the MIT from another scheme.

If either of those scenarios transpire, the merchant risks higher decline rates for MIT transactions since the NTID is no longer recognized by the issuers or card schemes. Some acquirers have subscribed to a Visa service called the "MIT Service" which can provision new NTID's. Spreedly recommends that you speak with your PSP to determine whether or not your PSP supports the Visa MIT service and how transactions which fall under these scenarios should be accounted for in order to optimize approval rates.

Note: Spreedly is in discussions to handle these scenarios with our partners on your behalf. When updates are available, we will provide instructions in this page.

FAQs

  1. Does Spreedly save the NTID value even if the stored_credential_initiator is not supplied? Yes, if the gateway is in our list of supported stored credential gateways we will save the NTID if the gateway provides it in the response. If the gateway is not in the list then we will not store the network transaction id.
  2. Does a merchant need to send the NTID or save it on their side? No, Spreedly stores the stored credential values in the stored_credential_usage[:GATEWAY_TYPE] field that is exposed in the show payment method response.
  3. Is a verification a valid CIT? According to Visa, a verification is not considered best practice for the initial CIT. They recommend performing an authorize or purchase as the initial CIT.
  4. If I want to request a MOTO 3DS exemption, is that a CIT or MIT transaction? The MOTO 3DS exemption is considered a cardholder present transaction. If you would like to set that transaction up for future usage then pass in cardholder in the stored_credential_initiator field. Additionally be sure to send the MOTO flag to the gateway as mentioned in our 3DS gateway specific exemptions guide.
  5. My MIT transactions are failing after account updater detected a portfolio swap, why is that? Network transaction ids are provided by either Visa or Mastercard and are used by the issuer’s authorization logic. When a portfolio swap occurs the network transaction ids are considered invalid. Our recommendation here is to perform a new CIT transaction to obtain a new NTID or prompt the cardholder for a new payment method. To know if a transaction was updated by Account Updater, you can either look in the callbacks that Spreedly will send following an AU update or call the PaymentMethod#Transactions endpoint and look for a ReplacePaymentMethod transaction with a change in the card_type field.
  1. Why do I see both network_transaction_id and original_transaction_id on a payment method? Some gateways require sending the NTID of the original CIT transaction and others requrie the NTID of the latest transaction with that gateway.
  2. Why do I sometimese see scheme_issued key in the stored_credential_usage field of my payment method? Gateways that return CCPD NTIDs are interchangeable with other gateways that accept this value. Spreedly will store these CCPD NTIDs in a gateway-agnostic section to be used with the stored_credential_alternate_gateway to enable stored credential transactions across multiple gateway types.
  3. Why am I not seeing data in the stored_credential_usage[:scheme_issued] field for my payment methods? There can be two reasons, one is that the transacting gateway does not support CCPD NTIDs. For a list of gateways that support CCPD NTIDs please refer to our alternate gateway guide. The other reason is that this field only began populating NTIDs beginning May 1st, 2024 and previous payment methods were not backfilled to include this data.