Re-caching Sensitive Data

There are some parts of a payment method that Spreedly cannot retain, e.g. the CVV of a credit card. In some cases, it may be advantageous to resupply that information to be used for a transaction that’s about to be run. For these cases Spreedly provides the ability to re-cache sensitive data for an existing payment method so that you do not have to recollect the whole payment method.

Note: A credit card must be retained in your environment in order to re-cache its CVV.

Using a transparent redirect


<form accept-charset="UTF-8" action="https://core.spreedly.com/v1/payment_methods/YsgVRVHkSca6GQLaQl4tG1kV6iX/recache" method="POST">
  <fieldset>
    <input name="redirect_url" type="hidden" value="http://example.com/transparent_redirect_complete" />
    <input name="environment_key" type="hidden" value="C7cRfNJGODKh4Iu5Ox3PToKjniY" />
    <input name="utf8" type="hidden" value="✓" />

    <input name="data[how_many]" type="text" value="5" />
    <input name="data[some_other_data]" type="text" value="Here is some additional data" />

    <label for="credit_card_verification_value">Security Code</label>
    <input id="credit_card_verification_value" name="credit_card[verification_value]" type="text" />

    <button type='submit'>Submit Payment</button>
  </fieldset>
</form>

Note the POST url which includes the payment method token and recache – this is what lets Spreedly know that you’re re-caching sensitive information for an already tokenized payment method. Only sensitive fields can be re-cached (currently the verification_value for credit cards), and any already vaulted data will be ignored. This call is only for re-caching sensitive data - if you need to update a payment method, see Updating Payment Methods.

The data fields provided in the form will be attached to the RecacheSensitiveData transaction, and the transaction is also the token that you will receive back:


http://example.com/transparent_redirect_complete?token=RtnAX9yUndUh7DJvkJ4Eir6cuwW


curl https://core.spreedly.com/v1/transactions/RtnAX9yUndUh7DJvkJ4Eir6cuwW.xml \
  -u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ'

<transaction>
  <token>4BRUS4zmOqgW3IrUok46gvJvvzU</token>
  <transaction_type>RecacheSensitiveData</transaction_type>
  <succeeded type="boolean">true</succeeded>
  <message key="messages.transaction_succeeded">Succeeded!</message>
  <data>
    <how_many>5</how_many>
    <some_other_data>Here is some additional data</some_other_data>
  </data>
  <payment_method>
    <token>YsgVRVHkSca6GQLaQl4tG1kV6iX</token>
    <created_at type="dateTime">2017-07-27T17:51:32Z</created_at>
    <updated_at type="dateTime">2017-07-27T17:55:54Z</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>
  <created_at type="dateTime">2017-07-27T17:55:54Z</created_at>
  <updated_at type="dateTime">2017-07-27T17:55:54Z</updated_at>
</transaction>


env = Spreedly::Environment.new('C7cRfNJGODKh4Iu5Ox3PToKjniY', '4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ', base_url: 'https://core.spreedly.com')
env.find_transaction("RtnAX9yUndUh7DJvkJ4Eir6cuwW")


#<Spreedly::RecacheSensitiveData:0x007fe3328de1c8
@token="LTXvrETOtqwBuMDRvau6xWXJw1i",
@created_at="2017-07-27T17:51:32Z",
@updated_at="2017-07-27T17:51:53Z",
@state="",
@message="Succeeded!",
@succeeded="true",
@data="<how_many>5</how_many>\n    <some_other_data>Here is some additional data</some_other_data>",
@payment_method,=
#<Spreedly::CreditCard:0x007fe332948b40
@token="YsgVRVHkSca6GQLaQl4tG1kV6iX",
@created_at="2017-07-27T17:51:32Z",
@updated_at="2017-07-27T17:51:53Z",
@email="",
@storage_state="retained",
@data="",
@first_name="Joe",
@last_name="Jones",
@full_name="Joe Jones",
@month="3",
@year="2032",
@number="XXXX-XXXX-XXXX-4444",
@last_four_digits="4444",
@first_six_digits="555555",
@card_type="master",
@verification_value="XXX",
@address1="",
@address2="",
@city="",
@state="",
@zip="",
@country="",
@phone_number="",
@company="",
@fingerprint="b5fe350d5135ab64a8f3c1097fadefd9effb",
@eligible_for_card_updater="true",
@errors=[]>>

Using JavaScript

JavaScript provides an alternative to the transparent redirect when you’d like to avoid leaving your site, while still keeping sensitive data off your server.


curl https://core.spreedly.com/v1/payment_methods/"YsgVRVHkSca6GQLaQl4tG1kV6iX"/recache.xml?environment_key=C7cRfNJGODKh4Iu5Ox3PToKjniY \
    -H 'Origin: http://example.com' \
    -H 'X-Requested-With: XMLHttpRequest' \
    -H 'Content-Type: application/xml' \
    -d '<payment_method>
          <credit_card>
            <verification_value>123</verification_value>
          </credit_card>
        </payment_method>'

The curl example demonstrates what an XMLHttpRequest will send as an Origin header. When an HTML FORM is posted directly to Spreedly from a customer site, it too will include an Origin header, so your JavaScript request must include the X-Requested-With header to tell the API you do not intend to perform a transparent redirect. Without the X-Requested-With header, the response will report an error about a missing redirect_url.

Using JavaScript, assuming a CORS-capable XMLHttpRequest, your API call would be:

var card =   '<payment_method> \
      <credit_card> \
          <verification_value>123</verification_value> \
      </credit_card> \
  </payment_method>'

var url = "https://core.spreedly.com/v1/payment_methods/"YsgVRVHkSca6GQLaQl4tG1kV6iX"/recache.xml?environment_key=C7cRfNJGODKh4Iu5Ox3PToKjniY";

$.ajax({
  type: "POST",
  url: url,
  dataType: "xml",
  contentType: "application/xml",
  data: card
}).success(function(data) {
  console.log(data);
  alert(data.transaction.payment_method.token);
}).error(function(request, status, error) {
  console.log(error);
  alert('error');
});

Spreedly will give you back the following output:


<transaction>
  <token>9BO3CTAv9ovAI5L02GC2nLiwSGC</token>
  <transaction_type>RecacheSensitiveData</transaction_type>
  <succeeded type="boolean">true</succeeded>
  <message key="messages.transaction_succeeded">Succeeded!</message>
  <data nil="true"/>
  <payment_method>
    <token>TRnySzGx52k5oTbCv8NbW2IsSQJ</token>
    <created_at type="dateTime">2017-07-27T17:51:50Z</created_at>
    <updated_at type="dateTime">2017-07-27T17:51:51Z</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>
  <created_at type="dateTime">2017-07-27T17:51:51Z</created_at>
  <updated_at type="dateTime">2017-07-27T17:51:51Z</updated_at>
</transaction>

You can also use a JSONP call as well.

Unlike the previous methods, JSONP uses a GET call to recache data. While trying to use a GET call for other methods will still return a 200, the data will not actually get updated.

Here is an example:


curl "https://core.spreedly.com/v1/payment_methods/"YsgVRVHkSca6GQLaQl4tG1kV6iX"/recache.js?environment_key=C7cRfNJGODKh4Iu5Ox3PToKjniY&kind=credit_card&verification_value=423"

{
  "transaction": {
    "token": "QcgRgVaNWjG0evT1pvd1XaEn25Y",
    "created_at": "2017-07-27T17:51:52Z",
    "updated_at": "2017-07-27T17:51:52Z",
    "succeeded": true,
    "transaction_type": "RecacheSensitiveData",
    "retained": false,
    "message": "Succeeded!",
    "message_key": "messages.transaction_succeeded",
    "payment_method": {
      "token": "Z7za9WpJOVkXsxQM8TTknrdgS7u",
      "data": null,
      "storage_state": "retained",
      "email": null,
      "created_at": "2017-07-27T17:51:52Z",
      "updated_at": "2017-07-27T17:51:52Z",
      "errors": [

      ],
      "payment_method_type": "credit_card",
      "first_name": "Joe",
      "last_name": "Jones",
      "full_name": "Joe Jones",
      "card_type": "master",
      "last_four_digits": "4444",
      "first_six_digits": "555555",
      "month": 3,
      "year": 2032,
      "address1": null,
      "address2": null,
      "city": null,
      "state": null,
      "zip": null,
      "country": null,
      "phone_number": null,
      "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,
      "company": null,
      "verification_value": "XXX",
      "number": "XXXX-XXXX-XXXX-4444",
      "fingerprint": "b5fe350d5135ab64a8f3c1097fadefd9effb"
    }
  },
  "status": 200
}

Using a Direct API Call

There are times though when you may want to re-cache sensitive data in a more “manual” fashion with an API call.

Please note: Using this API call can significantly increase your PCI compliance requirements.


curl https://core.spreedly.com/v1/payment_methods/"YsgVRVHkSca6GQLaQl4tG1kV6iX"/recache.xml \
  -u 'C7cRfNJGODKh4Iu5Ox3PToKjniY:4UIuWybmdythfNGPqAqyQnYha6s451ri0fYAo4p3drZUi7q2Jf4b7HKg8etDtoKJ' \
  -H 'Content-Type: application/xml' \
  -d '<payment_method>
        <credit_card>
            <verification_value>123</verification_value>
        </credit_card>
      </payment_method>'

<transaction>
  <token>60svwNAAP2h7uhz2zyG3ob9yW2l</token>
  <transaction_type>RecacheSensitiveData</transaction_type>
  <succeeded type="boolean">true</succeeded>
  <message key="messages.transaction_succeeded">Succeeded!</message>
  <data nil="true"/>
  <payment_method>
    <token>UNu8MpywEYAnvzICv7vuYla1h1I</token>
    <created_at type="dateTime">2017-07-27T17:51:49Z</created_at>
    <updated_at type="dateTime">2017-07-27T17:51:49Z</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>
  <created_at type="dateTime">2017-07-27T17:51:49Z</created_at>
  <updated_at type="dateTime">2017-07-27T17:51:49Z</updated_at>
</transaction>