Skip to main content

Merchant Help

 

Affirm Merchant Help

In-Store Checkout

Overview

The In-Store Checkout API is an alternative way of initiating the Affirm checkout flow. Customers will receive an email and SMS message containing the checkout URL. Once they follow the link, the Affirm checkout flow will be presented, the same one used for all eCommerce flows. Completing the checkout will result in a browser redirect and an optional webhook request, which contains the checkout_token for Authorization.

Checkout

The default method to create an Affirm Checkout is by using our JavaScript Library. To accommodate an in-store experience, consumers must apply from their own device (to avoid security and privacy issues with their Affirm application). By using this endpoint, Affirm will send a text to the billing phone number provided, which will link the consumer to their online application.

You can optionally choose to provide Affirm with a webhook address, for server-to-server confirmation of the checkout_token (after a consumer has confirmed their loan). We will still POST the token to the user_confirmation_url, but using such a webhook can remove the possibility of client/browser errors, and expedite the update of the payment status in your order management system. Please reach out to mts@affirm.com if you wish to configure a webhook for your in-store integration.

Note: The In-Store API will only send SMS text messages in the Affirm Live environment. During Sandbox environment testing, please rely on email messages to receive the checkout URL (if not using the checkout API response to get the URL).

Definition

Parameters

The following Checkout object parameters contain the bulk of the data that needs to be passed. Data should be sent as the content of a POST to one of the URLs above. 

An example message is located at the bottom of this page.

Checkout Object

This is the data payload that gets POSTed to the Affirm API to initialize checkout. All numerical (Integer) values must be passed as integer USD cents (i.e., $25.00 is passed as 2500).

Field Name R/O/C Type Description
financing_program O String A unique financing program name that is provided to you by Affirm. If you have a custom financing program available, you can enter the name of it in this field. If the program is not available or the name is not valid, your default financing program will be used.
merchant R Object (Merchant) Merchant configuration for the checkout session.
shipping C Object (Consumer Details) Consumer's shipping details. Required if the item is being shipped.
billing R Object (Consumer Details) Consumer's billing details.
items R List (Item) A list of items being purchased.
discounts O List (Discount) A list of discounts being applied. The key of each discount is a unique identifier to the discount. The value of each discount is a Discount object.
metadata O Object (Metadata) A hash of keys to values for any metadata to be passed into checkout and stored. 'entity_name' is a protected key, and will show up in your settlement reporting.
order_id O String Your internal order id. This is stored for your own reference.
shipping_amount C Integer The total shipping amount. Required if the item is being shipped. All numerical (Integer) values must be passed as integer USD cents (i.e., $25.00 is passed as 2500).
tax_amount O Integer The total tax amount computed after all discounts have been applied. Defaults to 0. All numerical (Integer) values must be passed as integer USD cents (i.e., $25.00 is passed as 2500).
total R Integer The total amount of the checkout, less any discounts applied. This determines the total amount charged to the user. All numerical (Integer) values must be passed as integer USD cents (i.e., $25.00 is passed as 2500).

 

Merchant object

The merchant object contains the user_confirmation_url and user_cancel_url, which represent the two possible outcomes of the checkout attempt. The user goes to the confirmation_url if the user is approved and confirms their loan. The user goes to the cancel_url in all other cases (voluntary cancel, credit decline, identity verification issue, etc.). 

Field Name R/O/C Type Description
public_api_key R String API Key of the merchant creating the checkout request
user_confirmation_url R URL

URL that the customer is sent to if they successfully complete the Affirm checkout flow. 

A checkout_token will be sent to this URL in the POST request, and that checkout_token should be used to authorize the charge before the user is redirected to the order confirmation page.

user_cancel_url R URL

URL that the customer is sent to if the customer exits the Affirm checkout flow.

This is the same if the user voluntarily cancels or closes the window before completion, or if the user is denied. You should setup the cancel_url to be the checkout payment page, and you can also append analytics tags to the URL to help you identify who you may want to reach out to about alternative payment methods or reapplying.

user_confirmation_url_action O String Accepted values are: 'GET', 'POST'. Defaults to 'POST'. Preference is to use 'GET'. Read more here.
name O String

For phone sales implementation, you will always want to specify a merchant facing name. Otherwise, customers will see the 'Telesales' suffix on the end of your company name.

If you have multiple sites operating under a single Affirm account, you can override the external company/brand name that the customer sees. This affects all references to your company name in the Affirm UI.

 

Metadata Object

The metadata object is an optional portion of the Checkout Object. If desired, merchants may include within the object information such as the attributes of the store and employee associated with the transaction. The following is an exhaustive list of the fields that Affirm has standardized for merchants, but merchants are not limited to these fields should they wish to pass others, well.

Field Name R/O/C Type Description
employee_id O String Unique ID of the employee who processed the transaction.
employee_name O String Name of the employee who processed the transaction.
store_id O String

Unique ID of the store at which the transaction occured.

store_location O String Location of the store at which the transaction occurred.
(merchant-specified, e.g., store_region) O String, Integer, or Object Optionally, merchants may designate additional metadata fields for tracking purposes. As with the standardized metadata fields, field names should be concatenated with underscores.

 

Consumer Details

Consumer details are used in both the Billing and Shipping address values. It represents the consumers name, address, email address, and phone number.

Field Name R/O/C Type Description
name R Object (Name) Consumers name to be used with the address.
address R Object (Address) Consumers physical address.
phone_number C String Consumers phone number.
email O String Consumers email address.
Name
Field Name R/O/C Type Description
first C String Consumers first name. Either ("first" and "last") or ("full") must be passed.
last C String Consumers last name. Either ("first" and "last") or ("full") must be passed.
full C String Consumers full name. Either ("first" and "last") or ("full") must be passed.
Address
Field Name R/O/C Type Description
line1 R String First line of the consumers address.
line2 O String Second line of the consumers address.
city R String Consumers city.
state R String (2-character ISO State Code) Consumers State.
zipcode R String Consumers zip code.
country R String (2 or 3-character ISO Country Code) Consumers country. NOTE: The only values currently supported are "US" or "USA".

 

Item Object

The item object array should be built dynamically, based on the current cart contents. All numerical (Integer) values must be passed as integer USD cents (i.e., $25.00 is passed as 2500).

Field Name R/O/C Type Description
display_name R String The display name of the product.
sku R String The unique identifier (SKU) of the product.
unit_price R Integer The item individual price. All numerical (Integer) values must be passed as integer USD cents (i.e., $25.00 is passed as 2500).
qty R Integer The item quantity expressed as an integer.
item_image_url O URL The item's product image URL.
item_url O URL The item's product description page URL.

 

Discount Object

Field Name R/O/C Type Description
discount_amount R Integer Amount of the discount being applied. All numerical (Integer) values must be passed as integer USD cents (i.e., $25.00 is passed as 2500).
discount_display_name R String Friendly name of the discount being applied.

 

Syntax notes

  • All numerical values must be sent as integer USD cents ($25.00 -> 2500).
  • The items from a consumer's cart are stored in an object array. You should build this array dynamically by adding item objects to it based on cart contents.
  • The discount object uses the discount code as the name of the nested objects. As a result, you may have to construct each discount without the use of a strongly-typed class.

Response

The POST returns a JSON String. It will also send a text to the phone_number from the billing contact object. This String contains the URL the consumer should be directed to.

Field Name R/O/C Type Description
checkout_id R String Checkout ID for the consumer's application.

Exceptions

If there are any errors processing the request, an error object is returned. The contents of the error object contains details about the specific error.

Error Response Fields

Field R/O/C Type Description
field R String Field containing an incorrect or invalid value.
message R String Friendly message that describes the issue.
code R String Short code referencing the specific error.
type R String Type of error being returned.
status_code R String HTTP Status Code that was returned.

Possible code values

The list below contains all of the possible code values that can be returned by Affirm.

auth-declined
Charge authorization hold declined.
capture-greater-instrument
Charges on this instrument cannot be captured for more than the authorization hold amount.
capture-unequal-instrument
Charges on this instrument cannot be captured for an amount unequal to authorization hold amount.
capture-voided
Cannot capture voided charge.
partial-capture-instrument
Charges on this instrument cannot be partially captured.
refund-exceeded
Max refund amount exceeded.
refund-uncaptured
Cannot refund a charge that has not been captured.
refund-voided
Cannot refund voided charge.
capture-declined
Charge capture declined.
capture-limit-exceeded
Max capture amount on charge exceeded.
expired-authorization
Cannot capture expired charge authorization hold.
refund-expired
Charges on this instrument must be refunded within N days of capture.
financial-product-invalid
Please provide a valid financial product key.
invalid_field
An input field resulted in invalid request.
public-api-key-not-specified
Please provide a public API key.
public-api-key-invalid
Please provide a valid public API key.
public-api-key-wrong-environment
Please provide a live public API key when not using the sandbox environment.
public-api-key-inactive
Please provide an active public API key.
api-key-pair-not-specified
Please provide a API key pair.
private-api-key-invalid
Please provide a valid private API key.
api-key-pair-wrong-environment
Please provide a live API key pair when not using the sandbox environment.
api-key-pair-inactive
Please provide an active API key pair.
not_found
The resource(s) specified in the request could not be found.

Possible type values

The list below contains all of the possible type values that can be returned by Affirm.

invalid-request
A generic error that indicates request inputs were invalid.
unauthorized
API keys were invalid.

Possible status_code values

The list below contains all of the possible status_code values that can be returned by Affirm.

400
Request fields resulted in an error.
401
Authorization was unsuccessful.
404
The requested resource(s) could not be found.
50x
An internal server issue resulted in an error.

Receiving the checkout token

The checkout token can be returned to you one of three ways:

  1. Via a webhook to your server.
  2. Via a client redirect to your website.
  3. Via the checkout_id that you receive in the checkout initiation's response body.
Checkout_token via webhook

The best way to receive the checkout_token for a customer's Affirm payment. When the customer confirms their loan, Affirm will send a webhook request to a URL that you've provided your Affirm contact.

When webhook URL checkout_token delivery is enabled, the checkout_token will be sent via webhook in addition to the default checkout_token delivery method of the client redirect to the 'user_confirmation_url'.

Setup
  1. Setup a page/endpoint on your server that can receive the checkout_token via POST request.
  2. Provide the URL of the page/endpoint you've setup to your Affirm Partner Engineer or Client Success Manager contact. We will store the URL in our system.
Checkout_token via client redirect

This is the default way to receive the checkout_token. When the customer confirms their loan, they will be redirected to the 'user_confirmation_url' that you defined in the checkout_object that was sent when the checkout was initiated. The request for that 'user_confirmation_url' can use either GET or POST method, and the checkout_token will be included in the request body form data.

Checkout_token via checkout_id

When you initiate checkout via the In-Store Checkout API, the response body will contain both the redirect_url (the same one that the customer receives via email/SMS), and the checkout_id. The checkout_id can be used to query for the status of the checkout, and if the checkout is complete, the checkout_id will be the same as the checkout_token. Therefore, you can POST the checkout_id to Affirm and it will be equivalent to the checkout_token (assuming the checkout is confirmed/completed).

Authorize a charge

POST /api/v2/charges
Summary

Charge authorization occurs after a user has successfully completed the Affirm checkout flow and returns back to the merchant site. Authorizing the charge generates the charge ID that will be used to reference this charge moving forward. A charge is not fully created before being authorized, and thus is not visible in the 'read charge' response, nor in the User/Merchant Dashboard.

Authorization request

curl https://sandbox.affirm.com/api/v2/charges/
     -X POST
     -u "<public_api_key>:<private_api_key>"
     -H "Content-Type: application/json"
     -d '{"checkout_token": "<checkout_token>","order_id": "JKLM4321"}'
Options
  • Type: POST
  • Authorization: Basic
  • Content type: application/JSON
  • Data: JSON string
Data
checkout_token
required string. Unique token used to authorize a charge. Received to the user_confirmation_url
order_id
optional string. Identifies the order within the merchant's order management system that this charge corresponds to.

Authorization response

The response to your request will contain the full charge response object, which includes all of the information that was submitted when you initialized checkout in addition to the charge and transaction-level identifiers.

The only two pieces of information you need to parse from this charge response object are the 'amount' and the charge 'id' (highlighted below):

{
   "id:ALO4-UVGR",
   "created":"2016-03-18T19:19:04Z",
   "currency":"USD",
   "amount":6100,
   "auth_hold":6100,
   "payable":0,
   "void":false,
   "expires": "2016-04-18T19:19:04Z",
   "order_id":"JKLM4321",
   "events":[
      {
         "created":"2014-03-20T14:00:33Z",
         "currency":"USD",
         "id":"UI1ZOXSXQ44QUXQL",
         "transaction_id":"TpR3Xrx8TkvuGio0",
         "type":"auth"
      }
   ],
   "details":{
      "items":{
         "sweater-a92123":{
            "sku":"sweater-a92123",
            "display_name":"Sweater",
            "qty":1,
            "item_type":"physical",
            "item_image_url":"http://placehold.it/350x150",
            "item_url":"http://placehold.it/350x150",
            "unit_price":5000
         }
      },
      "order_id":"JKLM4321",
      "shipping_amount":400,
      "tax_amount":700,
      "shipping":{
         "name":{
            "full":"John Doe"
         },
         "address":{
            "line1":"325 Pacific Ave",
            "city":"San Francisco",
            "state":"CA",
            "zipcode":"94112",
            "country":"USA"
         }
      }
      "discounts": {
        "RETURN5": {
          "discount_amount":    500,
          "discount_display_name": "Returning customer 5% discount"
        },
        "PRESDAY10": {
          "discount_amount":    1000,
          "discount_display_name": "President's Day 10% off"
        }
      }
   }
}
  • id
  • created
  • currency
  • amount
  • auth_hold
  • payable
  • void
  • order_id
  • events
    • created
    • currency
    • id
    • transaction_id
    • type
  • details
    • items
      • product sku
        • sku
        • display_name
        • qty
        • item_type
        • item_image_url
        • item_url
        • unit_price
    • order_id
    • shipping_amount
    • tax_amount
    • shipping
      • name
        • full
      • address
        • line1
        • line2
        • city
        • state
        • zipcode
        • country
    • billing
      • name
        • full
      • address
        • line1
        • line2
        • city
        • state
        • zipcode
        • country
    • discounts
      • discount code
        • discount_amount
        • discount_display_name

 

  • Validate that the authorized amount equals the order total amount
  • If amount is valid, store the (charge) 'id' to reference the charge when performing the various charge actions: capture, void, refund, and update.
Authorization error handling

If the authorization request fails for some reason, you will setup error handling to block order creation and direct the user back to payment method selection.

Error HTTP status Message to display Action to take
Authorization failed 400 "There was an issue authorizing your Affirm loan. Please check out again or use a different payment method." Redirect user back to payment method selection.
Unauthorized 401 "There was an issue authorizing your Affirm loan. Please check out again or use a different payment method." Redirect user back to payment method selection.
Checkout_token expired 401 "There was an issue authorizing your Affirm loan. Please check out again or use a different payment method." Redirect user back to payment method selection.

 

Charge States

 

Status Description Actions triggered Available Charge Actions
Authorized

The charge has been authorized and a charge_id is provided in the authorization response to reference this charge moving forward.

The authorization will expire after 30 days (default).

  • Charge ID is generated
  • User receives a message:
    "Thanks for using Affirm! Once (merchant name) has processed your order, we'll send your first payment invoice. Check status at http://www.affirm.com/u"
  • Charge is now visible in the Merchant Dashboard
Capture, Void, Read, Update
Voided

The charge has been voided, or the authorization has expired, and no further actions can be taken.

  • User receives a message
Read
Captured

The charge has been captured and the merchant will receive their funds. The user will begin payments 30 days after the capture.

 

  • User receives a message:
    "Affirm charge confirmed for (amount) at (merchant). View more details and pay your bills at https://www.affirm.com/account"
  • Affirm transfers funds to merchant within 2-3 business days
  • Affirm sends invoice to customer for the first payment, due in 30 days.
Refund, Read, Update
Partially Refunded The charge has been partially refunded and there is still a positive balance on the loan.
  • User receives a message:
    "Affirm refund confirmed for (amount) from (merchant). View more details at https://www.affirm.com/account"
  • Affirm will withhold refunded amount from next settlement
Refund, Read, Update
Refunded The charge has fully refunded and there is a zero balance on the loan.
  • User receives a message:
    "Affirm refund confirmed for (amount) from (merchant). View more details at https://www.affirm.com/account"
  • Affirm will withhold refunded amount from next settlement
Read
disputed A dispute has been opened and the charge is essentially refunded.   None
dispute_refunded A dispute has been resolved in the customer's favor and the refund stays in effect.   None

 

Charge Actions

The charge actions described on this page should all be integrated into your back-end order management system, where you would normally be fulfilling orders and processing payments/refunds/cancelations.

 

Read

GET /api/v2/charges/<charge_id>
  • Read the charge information for a specific charge, or all charges
  • Returns all of the checkout data along with current charge status
    • Status: authorized/captured/voided/refunded/partially-refunded
  • Useful for updating your records or OMS with the current state of a charge before charge actions are performed
  • Can keep your system in sync with Affirm if your staff will be manually managing loans in the Merchant Dashboard
Read request

Read a single charge: 

curl https://sandbox.affirm.com/api/v2/charges/CHARGE_ID/
     -X GET
     -u "public_key:private_key"

 

Read multiple charges: 

curl https://sandbox.affirm.com/api/v2/charges/?limit=5&before=1234-ABCD
     -X GET
     -u "public_key:private_key"

 

URL

 

If no <charge_id> is specified,  a list of charges will be returned, and you can define how the results are paginated using the query string parameters below:

Query String
limit
optional integer. Number of charges to be included in the response
before
optional string. Returns a list of charges that were created before the given charge ID.
after
optional string. Returns a list of charges that were created after the given charge ID.

Read response

{
   "id:ALO4-UVGR",
   "status": "auth",
   "created":"2016-03-18T19:19:04Z",
   "currency":"USD",
   "amount":6100,
   "auth_hold":6100,
   "payable":0,
   "void":false,
   "expires": "2016-04-18T19:19:04Z",
   "order_id":"JKLM4321",
   "events":[
      {
         "created":"2014-03-20T14:00:33Z",
         "currency":"USD",
         "id":"UI1ZOXSXQ44QUXQL",
         "transaction_id":"TpR3Xrx8TkvuGio0",
         "type":"auth"
      }
   ],
   "details":{
      "items":{
         "sweater-a92123":{
            "sku":"sweater-a92123",
            "display_name":"Sweater",
            "qty":1,
            "item_type":"physical",
            "item_image_url":"http://placehold.it/350x150",
            "item_url":"http://placehold.it/350x150",
            "unit_price":5000
         }
      },
      "order_id":"JKLM4321",
      "shipping_amount":400,
      "tax_amount":700,
      "shipping":{
         "name":{
            "full":"John Doe"
         },
         "address":{
            "line1":"325 Pacific Ave",
            "city":"San Francisco",
            "state":"CA",
            "zipcode":"94112",
            "country":"USA"
         }
      }
      "discounts": {
        "RETURN5": {
          "discount_amount":    500,
          "discount_display_name": "Returning customer 5% discount"
        },
        "PRESDAY10": {
          "discount_amount":    1000,
          "discount_display_name": "President's Day 10% off"
        }
      }
   }
}
  • id
  • status
  • created
  • currency
  • amount
  • auth_hold
  • payable
  • void
  • order_id
  • events
    • created
    • currency
    • id
    • transaction_id
    • type
  • details
    • items
      • product sku
        • sku
        • display_name
        • qty
        • item_type
        • item_image_url
        • item_url
        • unit_price
    • order_id
    • shipping_amount
    • tax_amount
    • shipping
      • name
        • full
      • address
        • line1
        • line2
        • city
        • state
        • zipcode
        • country
    • billing
      • name
        • full
      • address
        • line1
        • line2
        • city
        • state
        • zipcode
        • country
    • discounts
      • discount code
        • discount_amount
        • discount_display_name

 

Capture

POST /api/v2/charges/<charge_id>/capture

This captures the funds of an authorized charge, and is the same as capturing a typical credit card transaction.  

Once a loan is captured:

  • User receives a notice that the charge is captured.
  • User's first payment is due to Affirm in 30 days.
  • Affirm pays the merchants within 2-3 business days.
  • Full or partial refunds can be processed within 120 days.
Capture request

curl https://sandbox.affirm.com/api/v2/charges/CHARGE_ID/capture
     -X POST
     -u "(public_api_key):(private_api_key)"
     -H "Content-Type: application/json"
     -d '{"order_id": "JKLM4321", "shipping_carrier": "USPS", "shipping_confirmation": "1Z23223"}'
URL
Data
order_id
optional string. Your internal order id. This is stored for your own future reference.
shipping_carrier
optional string. The shipping carrier used to ship the items in the charge.
shipping_confirmation
optional string. The tracking number for the shipment.

Capture response

{
    "fee": 600,
    "created": "2016-03-18T00:03:44Z",
    "order_id": "JKLM4321",
    "currency": "USD",
    "amount": 6100,
    "type": "capture",
    "id": "O5DZHKL942503649",
    "transaction_id": "6dH0LrrgUaMD7Llc"
}
fee
integer. Portion of the captured amount that represents the merchant fee.
created
string. Timestamp for this event.
order_id
string. The order ID in your order management system.
amount
integer. Amount captured, including any fees.
type
string. Will always be "capture".
id
string. The ID for this API event.
transaction_id
string. The ID for the charge transaction.

 

Capture error handling

Error HTTP status Message to display Action to take
Captured failed 400    
Unauthorized 401    
Authorization expired 401    

Void

POST /api/v2/charges/<charge_id>/void

This cancels an authorized charge. For example, when a user decides to cancel their order before it's fulfilled.

Once a loan is voided:

  • It is permanently canceled and cannot be reauthorized.
  • User receives a notice that the transaction is canceled.
Void request

curl https://sandbox.affirm.com/api/v2/charges/CHARGE_ID/void
     -X POST
     -u "(public_api_key):(private_api_key)"
URL

Void response

{
  "type": "void",
  "id": "N5E9OXSIDJ8TKZZ9",
  "transaction_id": "G9TqohxBlRPWTGB2",
  "created": "2014-03-17T22:52:16Z",
  "order_id": "JLKM4321"
}
type
string. Always 'void'.
id
string. ID for this API event.
transaction_id
string. Transaction ID for this charge event.
created
string. Timestamp for this event.
order_id
optional string. Your internal order ID.

 

Void error handling

Error HTTP status Message to display Action to take
Authorization failed 400    
Unauthorized 401    
Checkout_token expired 401    

 

Refund

POST /api/v2/charges/<charge_id>/refund
  • You can apply any amount of refunds on a charge so long as there is a positive balance on the loan. 
  • Once a loan is fully refunded it cannot be reinstated.
  • Refunds can only be applied within 120 days of capturing the charge.
  • The amount you refund is based upon the original purchase price, just as if it was a normal credit card transaction. Interest and fees corresponding to the refunded amount are all automatically calculated on Affirm's end.
Refund request

curl https://sandbox.affirm.com/api/v2/charges/CHARGE_ID/refund \
     -X POST
     -u "(public_api_key):(private_api_key)"
     -H "Content-Type: application/json"
     -d '{"amount": 500}'
URL
Data
amount
optional integer. The amount to be refunded. If this parameter is missing or null, then by default the remaining loan balance will be refunded.

Refund response

{
  "created": "2014-03-18T19:20:30Z",
  "fee_refunded": 15,
  "amount": 500,
  "type": "refund",
  "id": "OWA49MWUCA29SBVQ",
  "transaction_id": "r86zdkHONPcaiVJJ"
}
created
string. Timestamp for this event.
fee_refunded
integer. Portion of the refunded amount that is subtracted from the merchant fee.
amount
integer. Amount refunded, including any fees.
type
string. Will always be "refund".
id
string. ID for this API event.
transaction_id
string. ID for this charge event.

 

Refund error handling

Error HTTP status Message to display Action to take
Authorization failed 400    
Unauthorized 401    
Checkout_token expired 401    

 

Update

POST /api/v2/charges/<charge_id>/update
  • Update a charge with new shipping, order information or shipping address
    • Shipment tracking number
    • Shipping carrier
    • Order ID
    • Shipping address
  • Shipping information is used by the Affirm customer service staff to see the fulfillment/delivery status of an order
  • Order ID is used in reconciliation reports and other places where Affirm charges need to be associated with internal order IDs
  • Shipping address is used to validate and update the shipping address in Affirm after the order is placed. If shipping address provided in the update request fails validation, an error is returned and the shipping address is not updated.
Update request

curl https://sandbox.affirm.com/api/v2/charges/CHARGE_ID/update
     -X POST
     -u "(public_api_key):(private_api_key)"
     -H "Content-Type: application/json"
     -d '{"order_id": "JLKM4321", "shipping_carrier": "USPS", "shipping_confirmation": "1Z23223", "shipping": {"name":{ "full": "John Doe"},"address": {"line1": "325 Pacific Ave", "state": "CA", "city": "San Francisco", "zipcode": "94111", "country": "USA"}}}'
URL
Data
order_id
optional string. Your internal order ID
shipping_carrier
optional string. The shipment carrier (e.g., "UPS").
shipping_confirmation
optional string. The shipment tracking number.
shipping
optional object. Customer shipping information.
 

Update response

{  
   "created":"2016-11-30T21:07:47Z",
   "order_id":"JLKM4321",
   "shipping_confirmation":"1Z23223",
   "shipping":{  
      "name":{  
         "full":"John Doe"
      },
      "address":{  
         "city":"San Francisco",
         "state":"CA",
         "zipcode":"94111",
         "line1":"325 Pacific Ave",
         "country":"USA"
      }
   },
   "shipping_carrier":"USPS",
   "type":"update",
   "id":"EILMLQLZPGC742HO"
}
created
string. Timestamp for this event.
id
string. ID for this API event.
order_id
optional string. Your internal order ID.
shipping_carrier
optional string. Shipment carrier (e..g, 'UPS').
shipping_confirmation
optional string. Shipment tracking number. 
shipping
optional object. Customer shipping address information.
 

Testing

Sandbox transactions
  1. Once you initiate checkout, you'll see the account creation screen.
    • If you've already created an account, click the 'Log In' button
    • If you haven't created an account, create one now.
      • Any First and last name
      • Valid email address format
      • Valid (random) US cell phone number
      • Birthdate longer than 18 years ago
      • Any four digits
  2. You'll be asked to enter a PIN number, use '1234'. We do not text you a PIN number in the Sandbox environment
  3. You will always see 3, 6, and 12 month terms.
  4. Once you click the 'Confirm' button, you'll be redirected to the user_confirmation_url with the checkout_token.
Live transactions
  • Do not use your own personal account to do test transactions in the Affirm live environment
  • Affirm furnishes loan and repayment information to credit bureaus. Capturing arbitrary test loans could impact your actual credit score.
  • Please contact your Engagement Manager who is coordinating your launch, or merchanthelp@affirm.com to conduct tests in the live environment.

Error Messages

auth-declined
Charge authorization hold declined.
capture-greater-instrument
Charges on this instrument cannot be captured for more than the authorization hold amount.
capture-unequal-instrument
Charges on this instrument cannot be captured for an amount unequal to authorization hold amount.
capture-voided
Cannot capture voided charge.
partial-capture-instrument
Charges on this instrument cannot be partially captured.
refund-exceeded
Max refund amount exceeded.
refund-uncaptured
Cannot refund a charge that has not been captured.
refund-voided
Cannot refund voided charge.
capture-declined
Charge capture declined.
capture-limit-exceeded
Max capture amount on charge exceeded.
expired-authorization
Cannot capture expired charge authorization hold.
refund-expired
Charges on this instrument must be refunded within N days of capture.
financial-product-invalid
Please provide a valid financial product key.
invalid_field
An input field resulted in invalid request.
public-api-key-not-specified
Please provide a public API key.
public-api-key-invalid
Please provide a valid public API key.
public-api-key-wrong-environment
Please provide a live public API key when not using the sandbox environment.
public-api-key-inactive
Please provide an active public API key.
api-key-pair-not-specified
Please provide a API key pair.
private-api-key-invalid
Please provide a valid private API key.
api-key-pair-wrong-environment
Please provide a live API key pair when not using the sandbox environment.
api-key-pair-inactive
Please provide an active API key pair.
not_found
The resource(s) specified in the request could not be found.

Logging

Merchant Dashboard

The Sandbox and Live Merchant Dashboard displays:

  • API calls
  • Authorized charges
API Calls
  • /checkout/
    • Initiates checkout.
    • 200 response indicates that the user was redirected to Affirm to complete the checkout
  • /charges/
    • Authorizes charges.
    • 200 response indicates the charge was authorized
  • /charges/<charge_id>
    • Reads charges
  • /charges/<charge_id>/capture
    • Captures the charge
    • 200 response indicates the action was completed successfully
  • /charges/<charge_id>/void
    • Voids an authorized charge
    • 200 response indicates the action was completed successfully
  • /charges/<charge_id>/refund
    • Refunds a captured charge
    • 200 response indicates the action was completed successfully
  • /charges/<charge_id>/update
    • Updates a charge with new shipping information
    • 200 response indicates the action was completed successfully

Examples

Checkout Configuration Example:

Below is an example of a Checkout Configuration to submit to Affirm:

{
      "merchant": {
        "public_api_key":               "ABCDEF123456",
        "user_confirmation_url":        "https://secure.merchantsite.com/affirm/confirm",
        "user_cancel_url":              "https://secure.merchantsite.com/affirm/cancel"
        "user_confirmation_url_action": "POST",
        "name":                         "Your Customer-Facing Merchant Name"
      },
      "shipping":{
        "name":{
          "first":                      "John",
          "last":                       "Doe"
          // You can include the full name instead
          // "full" :                   "John Doe"
        },
        "address":{
          "line1":                       "325 Pacific Ave",
          "city":                        "San Francisco",
          "state":                       "CA",
          "zipcode":                     "94112",
          "country":                     "USA"
        },
        "phone_number":                  "4151234567",
        "email":                         "johndoe@gmail.com"
      },
      "billing":{
        "name":{
          "full":                        "John Doe"
        },
        "address":{
          "line1":                       "325 Pacific Ave",
          "city":                        "San Francisco",
          "state":                       "CA",
          "zipcode":                     "94112",
          "country":                     "USA"
        },
        // This is the phone number to which Affirm will send a text, linking to the consumer's online application
        "phone_number":                  "4151234567", 
        "email":                         "johndoe@gmail.com"
      },
      "items": [
        {
            "display_name":              "Awesome Pants",
            "sku":                       "ABC-123",
            "unit_price":                1999,        //in cents, this represents $19.99
            "qty":                       3,
            "item_image_url":            "http://merchantsite.com/images/awesome-pants.jpg",
            "item_url":                  "http://merchantsite.com/products/awesome-pants.html"
        }
      ],

      "discounts": {
        "RETURN5": {
          "discount_amount":             500,         //in cents
          "discount_display_name":       "Returning customer 5% discount"
        },
        "PRESDAY10": {
          "discount_amount":             1000,
          "discount_display_name":       "President's Day 10% off"
        }
      },

      "metadata": {
        "shipping_type":                 "UPS Ground",
        "entity_name":                   "internal-sub_brand-name"
      },

      "order_id":                        "JKLMO4321", //Your unique transaction reference
      "shipping_amount":                 1000,        //in cents
      "tax_amount":                      500,         //in cents
      "total":                           6997         //in cents
  });

In addition to sending the consumer a text at the phone_number associated with the billing object, the result is a JSON object including the checkout_id

{"checkout_id": "ABCDEFGH12345678"}

A full PHP example of how this might be used is below:

<?php
    $endpoint = "https://api.affirm.com/api/v2/checkout/store";
    $rawCheckout = array( 
        "merchant" => array (
            "public_api_key" => "ABCDEF123456",
            "user_cancel_url" => "https://secure.merchantsite.com/affirm/cancel",
            "user_confirmation_url" => "https://secure.merchantsite.com/affirm/confirm",
        ),
        "items" => array (
            array (
                "display_name" => "Awesome Pants",
                "item_image_url" => "http://merchantsite.com/images/awesome-pants.jpg",
                "item_url" => "http://merchantsite.com/images/awesome-pants.html",
                "qty" => "1",
                "sku" => "ABC-123",
                "unit_price" => "10000"
            )
        ),
        "shipping" => array (
            "address" => array (
                "city" => "San Francisco",
                "line1" => "225 Bush St",
                "state" => "CA",
                "zipcode" => "94104"
            ),
            "name" => array (
                "full" => "John Doe"
            )
        ),
        "billing" => array (
            "address" => array (
                "city" => "San Francisco",
                "line1" => "225 Bush St",
                "state" => "CA",
                "zipcode" => "94104"
            ),
            "name" => array (
                "full" => "John Doe"
            ),
            "phone_number" => "415-555-5555",
            "email" => "johndoe@gmail.com"
        ),
        "total" => "10000"
    );
            
    $data = json_encode($rawCheckout);
    $contentType = "application/json";
    
    $process = curl_init($endpoint);
    curl_setopt($process, CURLOPT_HTTPHEADER, array('Content-Type: ' . $contentType));
    curl_setopt($process, CURLOPT_HEADER, false);
    curl_setopt($process, CURLOPT_VERBOSE, false);
    curl_setopt($process, CURLOPT_POST, TRUE);
    curl_setopt($process, CURLOPT_POSTFIELDS, $data);
    curl_setopt($process, CURLOPT_RETURNTRANSFER, TRUE);
    $return = curl_exec($process);
        
    $rCode = curl_getinfo( $process, CURLINFO_RESPONSE_CODE );
    
    if ($rCode == 200) {
        print( "<p><h2>Success!</h2><br>");
        print( $return );
    }
    else {
        http_response_code($rCode);
        print_r( "<p><h2>There was an error!</h2><br>" );
        print_r( $return );
    }
    curl_close( $process );
?>