Adding Payment Methods Using the API

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

There are times though when you may want to create a payment method in a more “manual” fashion with an API call.

PLEASE NOTE: Using this API call can significantly increase your PCI compliance requirements since sensitive cardholder data will be touching your servers.

Adding a payment method

You can add a payment method like so:


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>2032</year>
        </credit_card>
        <email>joey@example.com</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 any arbitrary data you’d like to attach to the payment method. We explain this field in more detail on the transparent redirect page.

You’ll receive back 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>joey@example.com</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>


env = Spreedly::Environment.new('C7cRfNJGODKh4Iu5Ox3PToKjniY', '4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ', base_url: 'https://core.spreedly.com')
env.add_credit_card(
  email: 'perrin@wot.com',
  number: '5555555555554444',
  month: 4,
  year: 2021,
  last_name: 'Aybara',
  first_name: 'Perrin',
  data: "occupation: Blacksmith"
)

The data attribute can be any arbitrary data you’d like to attach to the payment method. We explain this field in more detail on the transparent redirect page.

You’ll receive back the following output:


#<Spreedly::AddPaymentMethod:0x007fe33391e308
@token="E43b7u7QVzCtZc4sDY6PBOMrMps",
@created_at="2017-07-27T17:51:28Z",
@updated_at="2017-07-27T17:51:28Z",
@state="succeeded",
@message="Succeeded!",
@succeeded="true",
@retained="false",
@payment_method,=
#<Spreedly::CreditCard:0x007fe33390c928
@token="NLaBzdHpAgu17Q76zkAjP9E8Vpl",
@created_at="2017-07-27T17:51:28Z",
@updated_at="2017-07-27T17:51:28Z",
@email="perrin@wot.com",
@storage_state="cached",
@data="occupation: Blacksmith",
@first_name="Perrin",
@last_name="Aybara",
@full_name="Perrin Aybara",
@month="4",
@year="2021",
@number="XXXX-XXXX-XXXX-4444",
@last_four_digits="4444",
@first_six_digits="555555",
@card_type="master",
@verification_value="",
@address1="",
@address2="",
@city="",
@state="",
@zip="",
@country="",
@phone_number="",
@company="",
@fingerprint="b5fe350d5135ab64a8f3c1097fadefd9effb",
@eligible_for_card_updater="true",
@errors=[]>>

Retain on Create

You can always use the retain API call to store a card in Core’s vault. There is another option though; you can choose to retain the card immediately as it’s added to avoid making a second API call. You can do so by setting 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>2032</year>
        </credit_card>
        <retained>true</retained>
      </payment_method>'

You’ll 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>


env = Spreedly::Environment.new('C7cRfNJGODKh4Iu5Ox3PToKjniY', '4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ', base_url: 'https://core.spreedly.com')
env.add_credit_card(
  email: 'perrin@wot.com',
  number: '5555555555554444',
  month: 4,
  year: 2021,
  last_name: 'Aybara',
  first_name: 'Perrin',
  data: "occupation: Blacksmith",
  retained: true
)

You’ll notice that the storage_state of the payment method is retained.


#<Spreedly::AddPaymentMethod:0x007fe332b55d20
@token="3KvxyBOP2jbsZaPTcizGg7Sdif3",
@created_at="2017-07-27T17:51:32Z",
@updated_at="2017-07-27T17:51:32Z",
@state="succeeded",
@message="Succeeded!",
@succeeded="true",
@retained="true",
@payment_method,=
#<Spreedly::CreditCard:0x007fe333b650a8
@token="BV7tv7B0aPefj8mBwd63ZELRFgl",
@created_at="2017-07-27T17:51:32Z",
@updated_at="2017-07-27T17:51:32Z",
@email="perrin@wot.com",
@storage_state="retained",
@data="occupation: Blacksmith",
@first_name="Perrin",
@last_name="Aybara",
@full_name="Perrin Aybara",
@month="4",
@year="2021",
@number="XXXX-XXXX-XXXX-4444",
@last_four_digits="4444",
@first_six_digits="555555",
@card_type="master",
@verification_value="",
@address1="",
@address2="",
@city="",
@state="",
@zip="",
@country="",
@phone_number="",
@company="",
@fingerprint="b5fe350d5135ab64a8f3c1097fadefd9effb",
@eligible_for_card_updater="true",
@errors=[]>>

Adding email and/or billing address to a payment method

You also have the ability to specify additional fields on a credit card such that you can store things like email, billing address, and/or phone number with the payment method. For example:


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>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>
        </credit_card>
        <email>joey@example.com</email>
      </payment_method>'

<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>joey@example.com</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>


env = Spreedly::Environment.new('C7cRfNJGODKh4Iu5Ox3PToKjniY', '4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ', base_url: 'https://core.spreedly.com')
env.add_credit_card(
  email: 'perrin@wot.com',
  number: '5555555555554444',
  month: 4,
  year: 2021,
  last_name: 'Aybara',
  first_name: 'Perrin',
  data: "occupation: Blacksmith",
  address1: "33 Lane Road",
  address2: "Apartment 5",
  city: "Wanaque",
  state: "NJ",
  zip: "31331",
  country: "USA",
  phone_number: "919.331.3313",
  company: "Acme, Inc."
)


#<Spreedly::AddPaymentMethod:0x007fe33293f450
@token="aIh3C5iHUDhlBBM3Omp3g8xY51I",
@created_at="2017-07-27T17:51:29Z",
@updated_at="2017-07-27T17:51:29Z",
@state="succeeded",
@message="Succeeded!",
@succeeded="true",
@retained="false",
@payment_method,=
#<Spreedly::CreditCard:0x007fe33291cef0
@token="8aSD7sGdNAVKSEoaq79GFociwkc",
@created_at="2017-07-27T17:51:29Z",
@updated_at="2017-07-27T17:51:29Z",
@email="perrin@wot.com",
@storage_state="cached",
@data="occupation: Blacksmith",
@first_name="Perrin",
@last_name="Aybara",
@full_name="Perrin Aybara",
@month="4",
@year="2021",
@number="XXXX-XXXX-XXXX-4444",
@last_four_digits="4444",
@first_six_digits="555555",
@card_type="master",
@verification_value="",
@address1="33 Lane Road",
@address2="Apartment 5",
@city="Wanaque",
@state="NJ",
@zip="31331",
@country="USA",
@phone_number="919.331.3313",
@company="Acme, Inc.",
@fingerprint="b5fe350d5135ab64a8f3c1097fadefd9effb",
@eligible_for_card_updater="true",
@errors=[]>>

Adding shipping address to a payment method

You also have the ability to specify a shipping address like so:


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>2032</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>joey@example.com</email>
      </payment_method>'

<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>joey@example.com</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>


env = Spreedly::Environment.new('C7cRfNJGODKh4Iu5Ox3PToKjniY', '4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ', base_url: 'https://core.spreedly.com')
env.add_credit_card(
  email: 'perrin@wot.com',
  number: '5555555555554444',
  month: 4,
  year: 2021,
  last_name: 'Aybara',
  first_name: 'Perrin',
  data: "occupation: Blacksmith",
  shipping_address1: "33 Lane Road",
  shipping_address2: "Apartment 5",
  shipping_city: "Wanaque",
  shipping_state: "NJ",
  shipping_zip: "31331",
  shipping_country: "USA",
  shipping_phone_number: "919.331.3313"
)


#<Spreedly::AddPaymentMethod:0x007fe333b0c868
@token="DQZvItR7qP3CjJXdmQAj45iRwpP",
@created_at="2017-07-27T17:51:33Z",
@updated_at="2017-07-27T17:51:33Z",
@state="succeeded",
@message="Succeeded!",
@succeeded="true",
@retained="false",
@payment_method,=
#<Spreedly::CreditCard:0x007fe333b04028
@token="3TPbwMvuzFYMKXK8xs8jsSCO7UR",
@created_at="2017-07-27T17:51:33Z",
@updated_at="2017-07-27T17:51:33Z",
@email="perrin@wot.com",
@storage_state="cached",
@data="occupation: Blacksmith",
@first_name="Perrin",
@last_name="Aybara",
@full_name="Perrin Aybara",
@month="4",
@year="2021",
@number="XXXX-XXXX-XXXX-4444",
@last_four_digits="4444",
@first_six_digits="555555",
@card_type="master",
@verification_value="",
@address1="",
@address2="",
@city="",
@state="",
@zip="",
@country="",
@phone_number="",
@company="",
@fingerprint="b5fe350d5135ab64a8f3c1097fadefd9effb",
@eligible_for_card_updater="true",
@errors=[]>>

Adding a payment method without using an access secret

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

For this reason, Spreedly provides the ability to add a payment method in an unauthenticated fashion (requiring only the environment key but not the access secret). Since the call is originating from an insecure environment, the payment method won’t be automatically retained. Instead, you will need to make a follow-up call from a secure environment to retain it for future use.

When adding 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":"2032"
        },
        "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"
    }
  }
}