Credit Card Fingerprints

Fingerprinting assigns a randomly generated identifier to cards that share the same number (PAN), making it easy to identify when multiple payment methods represent the same underlying card. This is useful for merchants in a variety of scenarios, including loyalty programs, anomalous activity detection, and recognizing individual customers across different channels.

Using Fingerprints

Any credit card stored at Spreedly will be assigned a fingerprint and exposed in the API response as the “fingerprint” field:


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>
      </payment_method>'

<transaction>
  <token>976M88sl25OnH2FZUZtTPG0aChh</token>
  <created_at type="dateTime">2017-07-27T17:51:30Z</created_at>
  <updated_at type="dateTime">2017-07-27T17:51:30Z</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>CS7xwJYi2sMUEnyYhj1qhG5OFI4</token>
    <created_at type="dateTime">2017-07-27T17:51:30Z</created_at>
    <updated_at type="dateTime">2017-07-27T17:51:30Z</updated_at>
    <email nil="true"/>
    <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>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>b5fe350d5135ab64a8f3c1097fadefd9effb</fingerprint>
  </payment_method>
</transaction>

If multiple payment methods are created with the same credit card number, they will each be assigned the same fingerprint value. Note how these calls return unique payment method tokens, but the same fingerprint value:


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>
      </payment_method>'

<transaction>
  <token>976M88sl25OnH2FZUZtTPG0aChh</token>
  <created_at type="dateTime">2017-07-27T17:51:30Z</created_at>
  <updated_at type="dateTime">2017-07-27T17:51:30Z</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>CS7xwJYi2sMUEnyYhj1qhG5OFI4</token>
    <created_at type="dateTime">2017-07-27T17:51:30Z</created_at>
    <updated_at type="dateTime">2017-07-27T17:51:30Z</updated_at>
    <email nil="true"/>
    <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>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>b5fe350d5135ab64a8f3c1097fadefd9effb</fingerprint>
  </payment_method>
</transaction>


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>
      </payment_method>'

<transaction>
  <token>Wy4mVHIMzL6nU6z7h7pZhk4OAOy</token>
  <created_at type="dateTime">2017-07-27T17:51:31Z</created_at>
  <updated_at type="dateTime">2017-07-27T17:51:31Z</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>kWtFdiL4hsjeoMjjCXn2Itvk5y</token>
    <created_at type="dateTime">2017-07-27T17:51:31Z</created_at>
    <updated_at type="dateTime">2017-07-27T17:51:31Z</updated_at>
    <email nil="true"/>
    <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>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>b5fe350d5135ab64a8f3c1097fadefd9effb</fingerprint>
  </payment_method>
</transaction>

Fingerprints are not only exposed when payment methods are created, but any time a payment_method element is represented in an API response making them trivial to access at any point in the payment method lifecycle.

There is currently no way to query for payment methods based on the fingerprint, so it’s up to you to store the fingerprint values in your system to perform any necessary reconciliation or querying.

Fingerprint Uniqueness

Credit cards with the same number will always have the same fingerprint as long as they are stored in the same Spreedly environment. In other words, fingerprints are per-environment. No fingerprint will be the same across environments or customers, even if the same card number is stored.

Uniqueness cannot be guaranteed, but fingerprint values are constructed with a 0.1% chance of collision across 126 billion values.