Single Card Payment Method Distribution

If you need to send a single payment method to an HTTPS endpoint, use the single card form of payment method distribution. If you are looking to export more than one card at a time to an SFTP endpoint, please see batch export instead.

Provision a test receiver

Spreedly provides a test receiver that simulates the functionality of a production receiver, but does not deliver the request to a third-party endpoint. The test receiver will ‘echo’ the parsed and formatted request in the delivery response, with sensitive data scrubbed. This allows you to validate the deliver API request while ensuring the request is properly formatted using our provided receiver variables and functions. Additionally, the test receiver can only deliver test payment methods. Begin your integration by creating a test receiver pointing to the endpoint host (the https:// and domain name but not the path) you wish to deliver to.

Here, we want to simulate the delivery of payment methods to the URL https://spreedly-echo.herokuapp.com/. For more detail, see the API documentation.

$ curl https://core.spreedly.com/v1/receivers.json \
  -u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
  -H 'Content-Type: application/json' \
  -d '{
        "receiver": {
          "receiver_type": "test",
          "hostnames": "https://spreedly-echo.herokuapp.com",
          "credentials": [
            {
              "name": "app-id",
              "value": 1234,
              "safe": true
            },
            {
              "name": "app-secret",
              "value": 5678
            }
          ]
        }
      }'

$ curl https://core.spreedly.com/v1/receivers.xml \
  -u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
  -H 'Content-Type: application/xml' \
  -d '<receiver>
        <receiver_type>test</receiver_type>
        <hostnames>https://spreedly-echo.herokuapp.com</hostnames>
        <credentials>
          <credential>
            <name>app-id</name>
            <value>1234</value>
            <safe>true</safe>
          </credential>
          <credential>
            <name>app-secret</name>
            <value>5678</value>
          </credential>
        </credentials>
      </receiver>'

The response will include a token value identifying the new receiver, which you will use when you need to distribute card data from Spreedly to the receiver.

{
  "receiver": {
    "company_name": "TEST",
    "receiver_type": "test",
    "token": "TdXjq6sqBHpD1200iIvUhYy9x50",
    "hostnames": "https://spreedly-echo.herokuapp.com",
    "state": "retained",
    "created_at": "2020-02-13T18:38:04Z",
    "updated_at": "2020-02-13T18:38:04Z",
    "credentials": [
      {
        "name": "app-id",
        "value": 1234,
        "safe": true
      },
      {
        "name": "app-secret",
        "safe": false
      }
    ]
  }
}
<receiver>
  <company_name>TEST</company_name>
  <receiver_type>test</receiver_type>
  <token>NG7rSGp3MPJIWEXwKxZ5sr7tgvj</token>
  <hostnames>https://spreedly-echo.herokuapp.com</hostnames>
  <state>retained</state>
  <created_at type="dateTime">2020-02-13T18:38:04Z</created_at>
  <updated_at type="dateTime">2020-02-13T18:38:04Z</updated_at>
  <credentials type="array">
    <credential>
      <name>app-id</name>
      <value>1234</value>
      <safe>true</safe>
    </credential>
    <credential>
      <name>app-secret</name>
      <safe>false</safe>
    </credential>
  </credentials>
</receiver>

If you are provisioning a different test receiver that requires additional credentials, see the Credentials section below.

Deliver a payment method

Once you’ve specified where to deliver card data (i.e., the receiver), you have to specify what to deliver (i.e., the payment method and any other required fields). The best way to think about payment method distribution is that you send Spreedly the raw HTTP request structure and then Spreedly populates your request with the sensitive data from your credit card vault before sending the request to the receiver. Once you have a receiver provisioned, you need to tell Spreedly how to build the HTTP request, including the sensitive card data. This request structure is built using a simple templating language and the deliver API endpoint.

There are five basic properties that define the distribution of a payment method:

  • the token representing the payment method to be distributed,
  • the URL to distribute the payment method to,
  • the HTTP request headers,
  • the HTTP request method, and
  • the HTTP request body.

The exact content of these elements will be determined by the third-party receiver to which the payment method will be delivered. These elements may include information about the transaction, such as a product or flight number, the intended recipient of an order, or a payment amount. Please refer to the third-party endpoint you’re using in production for information about their expected format and fields.

A simple deliver request might look like the following:

curl https://core.spreedly.com/v1/receivers/IqHtfN2wEKLPHP9iFqIzX6as9yS/deliver.json \
  -u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
  -H 'Content-Type: application/json' \
  -d '{
        "delivery": {
          "payment_method_token": "56wyNnSmuA6CWYP7w0MiYCVIbW6",
          "url": "https://spreedly-echo.herokuapp.com",
          "headers": "Content-Type: application/json",
          "body": "{ \"product_id\": \"916598\", \"card_number\": \"{{credit_card_number}}\" }"
        }
      }'
curl https://core.spreedly.com/v1/receivers/IqHtfN2wEKLPHP9iFqIzX6as9yS/deliver.xml \
  -u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
  -H 'Content-Type: application/xml' \
  -d '<delivery>
        <payment_method_token>56wyNnSmuA6CWYP7w0MiYCVIbW6</payment_method_token>
        <url>https://spreedly-echo.herokuapp.com</url>
        <headers><![CDATA[Content-Type: application/json]]></headers>
        <body><![CDATA[{
    "product_id":"916593",
    "card_number":"{{ credit_card_number }}"
  }]]></body>
      </delivery>'

Template variables

When you invoke the deliver endpoint on the Spreedly API, you have to tell Spreedly how to format the HTTP request that will be sent to the receiver. The url, headers, and body values all accept template syntax that is evaluated when the deliver request is sent. These templates allow you to format the request in the structure required by the endpoint without directly accessing sensitive information.

For instance, if you need to create the following JSON request body to send to your receiver:

{
  "product_id":"916593",
  "card_number":"4111111111111111"
}

Then you would specify the deliver request body as follows:

{
  "product_id":"916593",
  "card_number":"{{ credit_card_number }}"
}

Any value that you want Spreedly to insert for you should be specified using template syntax: {{ variable_name }}. Spreedly will insert the value of the given variable that corresponds to the specified payment method represented by the payment_method_token element into your request template.

A list of all available variables can be found in the reference documentation here.

Template functions

A set of receiver functions is also available to dynamically modify values when a deliver request is sent. For instance, to send a basic authorization HTTP header, you would use the base64 function:

Authorization: Basic {{#base64}}{{ user }}:{{ password }}{{/base64}}

In the above example, base64 encodes the username and password values (which may have been set as credentials when initially provisioning the receiver). Assuming a user value of user and a password of Pa$$werd, the resulting value sent to the receiver will be

Authorization: Basic dXNlcjpQYSQkd2VyZA==

All receiver template functions wrap some content, which is then operated on. These functions require leading and trailing tags, which use the syntax {{#function}} and {{/function}}, respectively.

A list of all receiver functions can be found in the reference docs.

Provision a production receiver

Once you have completed testing with a test receiver, you will need to provision a production receiver. Production receiver types are more restricted in that they have a pre-specified hostname that must be allowed by Spreedly before they can be used. You will need to contact Spreedly directly to get your receiver endpoint and new receiver_type provisioned.

Once your receiver has been implemented by Spreedly, you can provision it using the receiver type given to you by Spreedly (or use one of our existing receivers listed below). Production receivers don’t accept hostnames since those values are hard-coded into the receiver:

$ curl https://core.spreedly.com/v1/receivers.json \
  -u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
  -H 'Content-Type: application/json' \
  -d '{
        "receiver": {
          "receiver_type": "sabre"
        }
      }'


{
  "receiver": {
    "company_name": "Sabre",
    "receiver_type": "sabre",
    "token": "7VdCtEYxttQ7bGMz0EjYZFRFMpH",
    "hostnames": "https://webservices.sabre.com, https://webservices3.sabre.com, https://webservices.havail.sabre.com",
    "state": "retained",
    "created_at": "2017-07-27T17:55:23Z",
    "updated_at": "2017-07-27T17:55:23Z",
    "credentials": null
  }
}
$ curl https://core.spreedly.com/v1/receivers.xml \
  -u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
  -H 'Content-Type: application/xml' \
  -d '<receiver>
        <receiver_type>sabre</receiver_type>
      </receiver>'


<receiver>
  <company_name>Sabre</company_name>
  <receiver_type>sabre</receiver_type>
  <token>MY9oI3uxM7Mu4Mafsqv505mCFOm</token>
  <hostnames>https://webservices.sabre.com, https://webservices3.sabre.com, https://webservices.havail.sabre.com</hostnames>
  <state>retained</state>
  <created_at type="dateTime">2017-07-27T17:55:24Z</created_at>
  <updated_at type="dateTime">2017-07-27T17:55:24Z</updated_at>
  <credentials nil="true"></credentials>
</receiver>

If you have a working payment method distribution integration with a test receiver, you should be able to replace the receiver token in your existing deliver call with the new receiver token when you are ready to move to production. You should also confirm that the url, headers and body are correctly formatted to work with the third-party API endpoint.

The full list of currently supported receivers and the API endpoints they are allowed to access is included in our documentation.

Credentials

If your receiver endpoint requires authentication, you can specify credentials on creation. These credentials will then be available as a variable when making the actual deliver request. Credentials are supplied as one or more name/value pairs. The safe property indicates values that are not sensitive (e.g., public keys and usernames). These values may be echoed back in receiver transcripts and other integration artifacts. Credentials that do not have safe=true are considered sensitive and will never be output in plain text anywhere except to the receiver within a deliver request.

Credentials should be used sparingly. You should specify credentials only if you have values you don’t want echoed in transcripts and other artifacts. Otherwise, it’s best to store dynamic values yourself and to insert them into the template you send to Spreedly. This approach is simpler and provides clear separation between Spreedly’s responsibility to manage sensitive data and your responsibility to format the request and to provide the rest of the template.

Recache CVVs

According to the PCI standard, CVVs can’t be persisted in long-term storage, even by a vaulting provider like Spreedly. If you need to include CVV data in your receiver request, you will need to recache the CVV first before invoking the deliver request. On successful completion of a receiver request, the CVV will be wiped from Spreedly’s data. Therefore, you will need to recache the CVV immediately prior to every receiver call.

Diagnose Errors

If you attempt to add a receiver using a receiver_type that is not available, you will receiver a 403 error response:

$ curl https://core.spreedly.com/v1/receivers.json \
  -u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
  -H 'Content-Type: application/json' \
  -d '{
        "receiver": {
          "receiver_type": "NOTREAL"
        }
      }'


{
  "errors": [
    {
      "key": "errors.unknown_receiver_type",
      "message": "The specified receiver_type is not supported"
    }
  ]
}
$ curl https://core.spreedly.com/v1/receivers.xml \
  -u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
  -H 'Content-Type: application/xml' \
  -d '<receiver>
        <receiver_type>NOTREAL</receiver_type>
      </receiver>'


<errors>
  <error key="errors.unknown_receiver_type">The specified receiver_type is not supported</error>
</errors>

Additionally, you can only specify hostnames for the test receiver type. Production receivers have their hostnames explicitly provided by Spreedly to ensure that the delivery endpoints are known and PCI compliant. If you attempt to specify your own hostname for a production receiver, you will receive an error:

$ curl https://core.spreedly.com/v1/receivers.json \
  -u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
  -H 'Content-Type: application/json' \
  -d '{
        "receiver": {
          "receiver_type": "sabre",
          "hostnames": "https://maninthemiddle.com"
        }
      }'


{
  "errors": [
    {
      "key": "errors.hostnames_not_allowed",
      "message": "You can't assign a custom hostname to a production receiver. Please don't specify a 'hostnames' property when adding a production receiver."
    }
  ]
}
$ curl https://core.spreedly.com/v1/receivers.xml \
  -u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
  -H 'Content-Type: application/xml' \
  -d '<receiver>
        <receiver_type>sabre</receiver_type>
        <hostnames>https://maninthemiddle.com</hostnames>
      </receiver>'


<errors>
  <error key="errors.hostnames_not_allowed">You can't assign a custom hostname to a production receiver. Please don't specify a 'hostnames' property when adding a production receiver.</error>
</errors>

Next

This guide explains the steps required to set up your own single-card payment method distribution integration but leaves out many details since every integration has unique requirements. To flesh out your receiver integration, the following resources may be useful: