Direct API

There are a variety of ways to send payment data to Spreedly. We recommend using the iFrame payment form or Spreedly Express to incur minimal PCI scope.

It is possible to create payment methods in a more "manual" fashion with an API call. Using this API call can significantly increase PCI compliance requirements since sensitive cardholder data will touch servers.

Adding a payment method

Use the following request:

curl https://core.spreedly.com/v1/payment_methods.xml \
  -u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
  -H 'Content-Type: application/xml' \
  -d '<payment_method>
        <credit_card>
            <first_name>Joey</first_name>
            <last_name>Jones</last_name>
            <number>5555555555554444</number>
            <verification_value>423</verification_value>
            <month>3</month>
            <year>2029</year>
        </credit_card>
        <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>
        <metadata>
          <key>String Value</key>
          <another_key>123</another_key>
          <final_key>true</final_key>
        </metadata>
      </payment_method>'

The data attribute can be arbitrary data attached to the payment method. This field is explained in detail in the transparent redirect guide.

The request will receive the following output:

<transaction>
  <token>PtobrGViSv8ykaU06MrdzSf7HUW</token>
  <created_at type="dateTime">2018-11-06T18:13:25Z</created_at>
  <updated_at type="dateTime">2018-11-06T18:13:26Z</updated_at>
  <succeeded type="boolean">true</succeeded>
  <transaction_type>AddPaymentMethod</transaction_type>
  <retained type="boolean">false</retained>
  <state>succeeded</state>
  <message key="messages.transaction_succeeded">Succeeded!</message>
  <payment_method>
    <token>aGdqGR0e4lD5OK2P0ooJJXqJXhE</token>
    <created_at type="dateTime">2018-11-06T18:13:25Z</created_at>
    <updated_at type="dateTime">2018-11-06T18:13:26Z</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>cached</storage_state>
    <test type="boolean">true</test>
    <metadata>
      <key>String Value</key>
      <another_key>123</another_key>
      <final_key>true</final_key>
    </metadata>
    <last_four_digits>4444</last_four_digits>
    <first_six_digits>555555</first_six_digits>
    <card_type>master</card_type>
    <first_name>Joey</first_name>
    <last_name>Jones</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>Joey Jones</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"/>
    <payment_method_type>credit_card</payment_method_type>
    <errors>
    </errors>
    <verification_value>XXX</verification_value>
    <number>XXXX-XXXX-XXXX-4444</number>
    <fingerprint>d0784fc53f352ca8be5ca364575d68aa7c5f</fingerprint>
  </payment_method>
</transaction>

Retain on Create

To store a card in the Spreedly vault, use a retain API call. Though this can always happen separately from the card's creation event, we also allow the ability to retain cards immediately to avoid that second API call. To do this, set the optional retained flag to true:

curl https://core.spreedly.com/v1/payment_methods.xml \
  -u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
  -H 'Content-Type: application/xml' \
  -d '<payment_method>
        <credit_card>
            <first_name>Joe</first_name>
            <last_name>Jones</last_name>
            <number>5555555555554444</number>
            <verification_value>423</verification_value>
            <month>3</month>
            <year>2029</year>
        </credit_card>
        <retained>true</retained>
      </payment_method>'

Notice that the storage_state of the payment method is retained.

<transaction>
  <token>FjgJD7inq0O7A4ydDsTc0zZs3G6</token>
  <created_at type="dateTime">2017-07-27T17:51:32Z</created_at>
  <updated_at type="dateTime">2017-07-27T17:51:32Z</updated_at>
  <succeeded type="boolean">true</succeeded>
  <transaction_type>AddPaymentMethod</transaction_type>
  <retained type="boolean">true</retained>
  <state>succeeded</state>
  <message key="messages.transaction_succeeded">Succeeded!</message>
  <payment_method>
    <token>YsgVRVHkSca6GQLaQl4tG1kV6iX</token>
    <created_at type="dateTime">2017-07-27T17:51:32Z</created_at>
    <updated_at type="dateTime">2017-07-27T17:51:32Z</updated_at>
    <email nil="true"/>
    <data nil="true"/>
    <storage_state>retained</storage_state>
    <test type="boolean">true</test>
    <last_four_digits>4444</last_four_digits>
    <first_six_digits>555555</first_six_digits>
    <card_type>master</card_type>
    <first_name>Joe</first_name>
    <last_name>Jones</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>Joe Jones</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"/>
    <payment_method_type>credit_card</payment_method_type>
    <errors>
    </errors>
    <verification_value>XXX</verification_value>
    <number>XXXX-XXXX-XXXX-4444</number>
    <fingerprint>b5fe350d5135ab64a8f3c1097fadefd9effb</fingerprint>
  </payment_method>
</transaction>

Adding email and/or billing address to a payment method

To specify additional fields like email, billing address, or phone number on a credit card and store those with the payment method:

curl https://core.spreedly.com/v1/payment_methods.xml \
  -u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
  -H 'Content-Type: application/xml' \
  -d '<payment_method>
        <credit_card>
            <first_name>Joe</first_name>
            <last_name>Jones</last_name>
            <number>5555555555554444</number>
            <verification_value>423</verification_value>
            <month>3</month>
            <year>2029</year>
            <address1>33 Lane Road</address1>
            <address2>Apartment 4</address2>
            <city>Wanaque</city>
            <state>NJ</state>
            <zip>31331</zip>
            <country>United States</country>
            <phone_number>919.331.3313</phone_number>
            <company>Acme Inc.</company>
        </credit_card>
        <email>[email protected]</email>
      </payment_method>'

Which will return:

<transaction>
  <token>GWW364zJoYkqDT7EeLyRhiR2evT</token>
  <created_at type="dateTime">2017-07-27T17:51:29Z</created_at>
  <updated_at type="dateTime">2017-07-27T17:51:29Z</updated_at>
  <succeeded type="boolean">true</succeeded>
  <transaction_type>AddPaymentMethod</transaction_type>
  <retained type="boolean">false</retained>
  <state>succeeded</state>
  <message key="messages.transaction_succeeded">Succeeded!</message>
  <payment_method>
    <token>Q787eA53AOdkJoob04R9olM2eLj</token>
    <created_at type="dateTime">2017-07-27T17:51:29Z</created_at>
    <updated_at type="dateTime">2017-07-27T17:51:29Z</updated_at>
    <email>[email protected]</email>
    <data nil="true"/>
    <storage_state>cached</storage_state>
    <test type="boolean">true</test>
    <last_four_digits>4444</last_four_digits>
    <first_six_digits>555555</first_six_digits>
    <card_type>master</card_type>
    <first_name>Joe</first_name>
    <last_name>Jones</last_name>
    <month type="integer">3</month>
    <year type="integer">2032</year>
    <address1>33 Lane Road</address1>
    <address2>Apartment 4</address2>
    <city>Wanaque</city>
    <state>NJ</state>
    <zip>31331</zip>
    <country>United States</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 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"/>
    <payment_method_type>credit_card</payment_method_type>
    <errors>
    </errors>
    <verification_value>XXX</verification_value>
    <number>XXXX-XXXX-XXXX-4444</number>
    <fingerprint>b5fe350d5135ab64a8f3c1097fadefd9effb</fingerprint>
  </payment_method>
</transaction>

Adding shipping address to a payment method

To specify a shipping address with the payment method:

curl https://core.spreedly.com/v1/payment_methods.xml \
  -u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
  -H 'Content-Type: application/xml' \
  -d '<payment_method>
        <credit_card>
            <first_name>Joe</first_name>
            <last_name>Jones</last_name>
            <number>5555555555554444</number>
            <verification_value>423</verification_value>
            <month>3</month>
            <year>2029</year>
            <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>United States</shipping_country>
            <shipping_phone_number>919.331.3313</shipping_phone_number>
        </credit_card>
        <email>[email protected]</email>
      </payment_method>'

Which returns:

<transaction>
  <token>Gtp0NhSLjT9bQvXIbvUcB4m2LMD</token>
  <created_at type="dateTime">2017-07-27T17:51:33Z</created_at>
  <updated_at type="dateTime">2017-07-27T17:51:33Z</updated_at>
  <succeeded type="boolean">true</succeeded>
  <transaction_type>AddPaymentMethod</transaction_type>
  <retained type="boolean">false</retained>
  <state>succeeded</state>
  <message key="messages.transaction_succeeded">Succeeded!</message>
  <payment_method>
    <token>ZD5hXMRudHhwuxwuqiGyqbyTmXY</token>
    <created_at type="dateTime">2017-07-27T17:51:33Z</created_at>
    <updated_at type="dateTime">2017-07-27T17:51:33Z</updated_at>
    <email>[email protected]</email>
    <data nil="true"/>
    <storage_state>cached</storage_state>
    <test type="boolean">true</test>
    <last_four_digits>4444</last_four_digits>
    <first_six_digits>555555</first_six_digits>
    <card_type>master</card_type>
    <first_name>Joe</first_name>
    <last_name>Jones</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>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>United States</shipping_country>
    <shipping_phone_number>919.331.3313</shipping_phone_number>
    <payment_method_type>credit_card</payment_method_type>
    <errors>
    </errors>
    <verification_value>XXX</verification_value>
    <number>XXXX-XXXX-XXXX-4444</number>
    <fingerprint>b5fe350d5135ab64a8f3c1097fadefd9effb</fingerprint>
  </payment_method>
</transaction>

Adding payment methods without an access secret

In some situations, it may be useful to add payment methods to Spreedly from an insecure environment, such as a native mobile application. Such environments should not have a Spreedly access secret persisted in local storage and thus cannot make an authenticated API call.

For this reason, Spreedly enables adding payment methods in an unauthenticated fashion, only requiring the specified environment key. Since the call orginates from an insecure environmnet, the payment method will not be automatically retained. Instead, it requires a follow-up call from a secure environment to retain the card for future use.

To add a payment method from an insecure environment, simply omit the authentication portion of the API request and pass in the environment key as a parameter:

curl https://core.spreedly.com/v1/payment_methods.json?environment_key=C7cRfNJGODKh4Iu5Ox3PToKjniY \
  -H 'Content-Type: application/json' \
  -d '{
    "payment_method":{
        "credit_card":{
            "first_name": "Joe",
            "last_name": "Jones",
            "number":"5555555555554444",
            "verification_value": "423",
            "month":"3",
            "year":"2029"
        },
        "data": {
            "my_payment_method_identifier": 448,
            "extra_stuff": {
                "some_other_things": "Can be anything really"
            }
        }
   }
   }'

The resulting storage state is cached, indicating it will be purged unless explicitly retained.

{
  "transaction": {
    "token": "KovbIpy2b4M9dl70F91vX8PulWo",
    "created_at": "2017-07-27T17:51:29Z",
    "updated_at": "2017-07-27T17:51:30Z",
    "succeeded": true,
    "transaction_type": "AddPaymentMethod",
    "retained": false,
    "state": "succeeded",
    "message_key": "messages.transaction_succeeded",
    "message": "Succeeded!",
    "payment_method": {
      "token": "1HarTtczL2QOT0xlNq7xfOHjS1E",
      "created_at": "2017-07-27T17:51:29Z",
      "updated_at": "2017-07-27T17:51:30Z",
      "email": null,
      "data": {
        "my_payment_method_identifier": 448,
        "extra_stuff": {
          "some_other_things": "Can be anything really"
        }
      },
      "storage_state": "cached",
      "test": true,
      "last_four_digits": "4444",
      "first_six_digits": "555555",
      "card_type": "master",
      "first_name": "Joe",
      "last_name": "Jones",
      "month": 3,
      "year": 2032,
      "address1": null,
      "address2": null,
      "city": null,
      "state": null,
      "zip": null,
      "country": null,
      "phone_number": null,
      "company": null,
      "full_name": "Joe Jones",
      "eligible_for_card_updater": true,
      "shipping_address1": null,
      "shipping_address2": null,
      "shipping_city": null,
      "shipping_state": null,
      "shipping_zip": null,
      "shipping_country": null,
      "shipping_phone_number": null,
      "payment_method_type": "credit_card",
      "errors": [

      ],
      "fingerprint": "b5fe350d5135ab64a8f3c1097fadefd9effb",
      "verification_value": "XXX",
      "number": "XXXX-XXXX-XXXX-4444"
    }
  }
}