Skip to main content

Merchant Help


Affirm Merchant Help

VirtualCard Server-Side Integration



Integration Points
  • Checkout flow
    • Add new Affirm payment method selector
  • Generate checkout session and initiate checkout
    • Write code to populate checkout_data and generate checkout session token on the back-end
    • If checkout data is valid:
      • Pass checkout_session_token to the front-end and initiate checkout.
    • If checkout data is invalid:
      • Pass error 'message' along to the front-end, and optionally highlight the field that's causing the error.
  • Order confirmation
    • Write success callback function to pass the returned checkout_session_token to the back-end
    • Write server-side script to request card details using the checkout_session_token
    • Populate card fields with the card details returned server-side
  • Order management system
    • Flag orders paid using Affirm as such, so it can be distinguished from other orders paid with a card 
User Flow

  1. User selects Affirm payment method during checkout
  2. User submits checkout
  3. Merchant submits checkout object JSON to /checkout/session endpoint and generates checkout_session_token
  4. Merchant stores returned checkout_session_token and passes to front-end
  5. Merchant populates 'affirm.checkout.open_vcn({ checkout_session_token })' object
  6. Merchant calls 'affirm.checkout.open_vcn()' function
  7. Affirm checkout pop-up window displays
  8. User logs in or creates an account with Affirm
  9. User selects loan terms
  10. User confirms loan terms
  11. Success callback is triggered
  12. Merchant stores card_token string
  13. Merchant calls Affirm /card/ API endpoint with card_token to retrieve card details
  14. Merchant parses returned card details
  15. Merchant populates card form fields or submits card auth request on back-end
  16. Merchant submits checkout page
  17. Merchant sends card authorization hold request via their payment gateway
  18. Merchant waits for success response
  19. Merchant redirects user to order confirmation page
  20. Order is complete


Merchant account setup

How to access your Affirm merchant account credentials.
Google Account

You can sign into the Affirm Dashboard using Google, or using your email and password.

  • If you'd like to use the Google sign-in option, and your work email address isn't associated with a Google account, you can do so here: Sign up without Gmail
  • If your company uses Gmail, or if you already have a Google account, you can select your work account after clicking the Google sign-in button.

Go to the Merchant Dashboard

You can access the sandbox environment Merchant Dashboard here:

Sign in with your Google account. If you aren't able to login, or receive a Internal Server Error, you may not have access to this dashboard or the dashboard may not be enabled. Please contact to restore your access.

Affirm Merchant Sandbox Dashboard

  1. Go to:
  2. Sign in with Google, or use your email and password.

Note: The work email address that you use to sign-in to the Affirm Dashboard must be granted access by your Dashboard's administrator, or your Affirm contact.

Need help accessing the Affirm Dashboard?

Retrieve Sandbox Keys

Once you are in the Merchant Dashboard, use the navigation bar on the left to access your API Keys. You will need the public key, private key, and financial product key that is displayed here.

  1. Hover over the profile icon area at the lower-left of the page.
    Screen Shot 2016-03-22 at 7.56.58 AM-2.png
  2. Click the API Keys link that appears.
    Screen Shot 2016-03-22 at 7.56.20 AM.png
  3. Copy the public, private, and financial product keys.


Generate Checkout Session Token

Using checkout session tokens

A checkout session token is generated server-side, so that the checkout initiation on the client-side does not involve any handling of sensitive customer information (PII).

Once a user's checkout data is altered, a new session token must be generated.

The checkout session token request can result in several possible errors, which should be handled by your server and then presented to the user on the front-end.

Request format

Method: POST
Authentication: Basic Auth, Base64 ASCII encoded public:private keypair
Body: JSON format checkout data

Response format

Body: JSON

Checkout data

    "name": "Your Customer-Facing Merchant Name"
      "full":"John Doe"
      "line1":"325 Pacific Ave",
      "city":"San Francisco",
      "full":"John Doe"
      "line1":"325 Pacific Ave",
      "city":"San Francisco",
  "items": [{
    "display_name":         "Awesome Pants",
    "sku":                  "ABC-123",
    "unit_price":           1999,
    "qty":                  3,
    "item_image_url":       "",
    "item_url":             ""

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

  "metadata": {
    "shipping_type":        "UPS Ground"

  "order_id":               "JKLMO4321",

  "shipping_amount":        1000,
  "tax_amount":             500,
  "total":                  6997
optional object. If you have multiple sites operating under a single Affirm account, you can override the external company/brand name that the customer sees using 'name'. This affects all references to your company name in the Affirm UI. 
optional object.  Customer contact information.
required object. Customer contact information.
required list. A list of item objects.
optional hash. A hash of coupon code to discount objects.
required integer. The total tax amount computed after all discounts have been applied; Defaults to 0.
required integer. The total shipping amount; Defaults to 0.
required integer. The total amount of the checkout. This determines the total amount charged to the user.
optional object. A hash of keys to values for any metadata to be passed into checkout and stored.
optional string. Your internal order id. This is stored for your own future reference.

Error response format

  "field": "object.field", 
  "message": "Some customer facing message.", 
  "code": "invalid_field", 
  "type": "invalid_request",
  "status_code": 40x|50x
string. Specific arameter/field associated with the returned error.
string. User-facing error message to be displayed on the front-end.
enum. Error code associated with this type of error.
string. Generic issue description.
integer. HTTP status code result for this request.

Example request

curl \
     --verbose \
     -X POST \
     -u "ARQBLCL7NAMBTZ7F:RkHBmVSP5ayC2rCUujwhArpGWPxpuTtv" \
     -H "Content-Type: application/json"\
     -d '{"merchant": {"name":"Your Customer Facing Merchant Name"},"items": [{"display_name": "Great product","item_url": "","item_image_url": "","qty": 2,"sku": "ABC123","unit_price": 10000}],"shipping": {"address": {"city": "San Francisco","line1": "633 Folsom Street","state": "CA","zipcode": "94107"},"name":{"full":"Ben Mo"},"phone_number":"9253232323"},"billing": {"address": {"city": "San Francisco","line1": "633 Folsom Street","state": "CA","zipcode": "94107"},"email":"","name":{"full":"Ben Mo"},"phone_number":"9253232323"},"total": 10000}'

Example success response


  "checkout_session_token": "ABCBLCL7NAMBTZDZ"
  "created": "2016-04-05T15:37:44.286033Z"
string. This event is triggered when the user successfully completes the Affirm checkout flow. The event data contains the virtual card token. This token will then be subsequently exchanged for the virtual card details via server-side API.
timestamp. This event is triggere


Example error response


  "field": "", 
  "message": "Please verify your name.", 
  "code": "invalid_field", 
  "type": "invalid_request",
  "status_code": 400
string. Specific arameter/field associated with the returned error.
string. User-facing error message to be displayed on the front-end.
enum. Error code associated with this type of error.
string. Generic issue description.
integer. HTTP status code result for this request.


Error Response Fields 

Edit section

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 

Edit section

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

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

Possible type values 

Edit section

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

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

Possible status_code values 

Edit section

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

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



Initiate Checkout

Embed Affirm's JS runtime code

  _affirm_config = {
    public_api_key:  "XXXXXXXXXXXXXXX",
    script:          ""
  (function(l,g,m,e,a,f,b){var d,c=l[m]||{},h=document.createElement(f),n=document.getElementsByTagName(f)[0],k=function(a,b,c){return function(){a[b]._.push([c,arguments])}};c[e]=k(c,e,"set");d=c[e];c[a]={};c[a]._=[];d._=[];c[a][b]=k(c,a,b);a=0;for(b="set add save post open empty reset on off trigger ready setProduct".split(" ");a<b.length;a++)d[b[a]]=k(c,e,b[a]);a=0;for(b=["get","token","url","items"];a<b.length;a++)d[b[a]]=function(){};h.async=!0;h.src=g[f];n.parentNode.insertBefore(h,n);delete g[f];d(g);l[m]=c})(window,_affirm_config,"affirm","checkout","ui","script","ready");
 // Use your live public API Key and script to point to Affirm production environment.

Note: replace the 'public_api_key' value with your own public API key. The API key must match the Affirm-environment you're referencing ('sandbox' or 'live').

Once the Affirm JS is initialized, the affirm.checkout method is made available:

  • affirm.checkout.open_vcn() - Initiates the VCN checkout window and accepts the checkout data object as its parameter.

The Affirm environment that's used is determined by the Affirm script URL that's defined in the _affirm_config.script:

var _affirm_config = {
    public_api_key:  "XXXXXXXXXXXXXXX",
    script:          ""

Checkout Object

You can define a separate checkout object to contain the top-level parameters for the open_vcn() method. This is where you define the name of the checkout_data object, success callback, and error callback.


      success: function(card_token) {
      error: error_callback_function
      checkout_session_token: checkoutSessionToken
required event. This event is triggered when the user successfully completes the Affirm checkout flow. The event data contains the virtual card token. This token will then be subsequently exchanged for the virtual card details via server-side API.
optional event. This event is triggered if the user is denied, or if they voluntarily cancel the Affirm checkout flow. The event data is generic, and only indicates that the checkout was canceled (even if they were actually denied).
required string. The checkout session token corresponds to checkout data submitted to the Affirm servers previously, which contains all the cart details, customer information, and metadata for the order.


Checkout Result

Once a user enters the Affirm checkout flow, there are two possible results of the checkout attempt: 'success' and 'error'. 


  • User is approved and confirms the Affirm loan terms: 
    • Success callback is triggered
    • Card token is returned in the event data
    • Server-side script sends the card token to the Affirm Virtual Card API and receives back the card details in the response
    • Custom Javascript fills in the card form on your checkout page automatically


  • User closes the window:
    • Error callback is triggered
    • 'reason: closed' is returned in the event data
    • You can display messaging to the user to 'select another payment method'
  • User is denied or uses the cancel icon:
    • Error callback is triggered
    • 'reason: canceled' is returned in the event data
    • You can display messaging to the user to 'select another payment method'
  • Pop-up fails to open:
    • Error callback is triggered
    • 'reason: popups_disabled' is returned in the event data
    • You can display instructions to the user to 'enable pop-ups or select another payment method'
Card Token

string. Can be ignored, for Affirm internal use.
string.  The card token that these card details correspond to.
timestamp. Time when this card token was generated.

Success Callback


      success: success_callback


Callback trigger

The success callback is triggered when the user confirms their Affirm loan terms in the pop-up window and is returned back to the checkout page.

Event data

The event data you need is:

  • Card token


Error Callback

Error Callback



      error: cancel_callback


 Event data

{reason: "closed"}
{reason: "canceled"}
{reason: "popups_disabled"}


Callback trigger

The error callback is triggered when the user cancels their application, closes the window, or the window is prevented from opening

Event data

The event data you need to utilize is:

  • Reason
    • closed
      • When the window is closed using the native window toolbar.
    • canceled
      • When the cancel icon or return button is clicked.
    • popups_disabled
      • When we detect that the pop up was blocked.

Callback behavior

Typically, your callback function will have the following behavior:

  1. Read the reason 
  2. Display a message if the user has disabled popups

Example function

function cancel_callback(e) {
   if(e.reason === "popups_disabled"){
      window.alert("Please enable pop-ups to checkout with Affirm");


Retrieve Card Details

Card details request format

GET /api/v2/checkout/<checkout_id>/checkout_instrument

This returns the card details associated with the checkout_id that was passed in the request URL. Once the card details are returned, the card can be authorized through your usual card gateway.

     -u "(public_api_key):(private_api_key)"


Card details response object

200 Response:

string. The First Data card number.
string. The First Data card pin.

400 Response if no First Data card exists for the given checkout.

500 Response if Affirm is unable to issue a card with First Data.


Charge Actions

All charge actions are done using your existing payment gateway and First Data. 

To redeem or reload the First Data card, simply use your payment gateway API and the First Data card number that was returned at checkout. 

Do not attempt to interact directly with the Affirm API for charges that were created. All charge interactions must be done through First Data.

Furthermore, the state of the Affirm charge as it appears in the Merchant Dashboard will not always reflect the charge state on the card network. For example, a refunded charge may not show as refunded on Affirm's side for up to 24 hours. Please refer to our merchant resources for customer-facing teams to help explain the relationship between charge actions on the gift card network (processed by the merchant) and the charge state in Affirm's system (visible to the customer).


Example Code

Create checkout session
curl \
     --verbose \
     -X POST \
     -u "ARQBLCL7NAMBTZ7F:RkHBmVSP5ayC2rCUujwhArpGWPxpuTtv" \
     -H "Content-Type: application/json"\
     -d '{"merchant": {"public_api_key":"ARQBLCL7NAMBTZ7F","user_cancel_url": "","user_confirmation_url": ""},"items": [{"display_name": "Great product","item_url": "","item_image_url": "","qty": 2,"sku": "ABC123","unit_price": 10000}],"shipping": {"address": {"city": "San Francisco","line1": "633 Folsom Street","state": "CA","zipcode": "94107"},"name":{"full":"Z"},"phone_number":"9253236612"},"billing": {"address": {"city": "San Francisco","line1": "633 Folsom Street","state": "CA","zipcode": "94107"},"email":"","name":{"full":"Z"},"phone_number":"9253236612"},"total": 10000}'
Retrieve card
     -X POST
     -u "(public_api_key):(private_api_key)"
     -H "Content-Type: application/json"
     -d '{"card_token": "ARZBLCL7NAMBTZ2D"}' 



Since all charges are captured through your existing card gateway, you will rely on the existing settlement reports that are generated by your card gateway to reconcile transactions.

Affirm will provide a monthly invoice so that any applicable merchant fees can be remitted, and a more detailed transaction-level spreadsheet will be provided to reconcile Affirm transactions.