close

Authentication API

Overview

Use this API to gain authorized access to AffiniPay merchant accounts.

Access Tokens

Request an Access Token

POST /oauth/token

This endpoint returns an access_token when you POST a valid grant_type parameter.

You can access merchant account details after you receive an access token. You must use your partner OAuth application client ID and secret to make this call.

Note: Before you can call the AffiniPay Payment Gateway API and manage transactions on a merchant's behalf, your partner OAuth application must use the access token to request gateway credentials.

ParameterDescription
client_idA unique 64-character, alphanumeric string used to identify your partner OAuth application in OAuth 2.0 web flows.
client_secretA unique 64-character, alphanumeric string used to authenticate your partner OAuth application in OAuth 2.0 web flows.
grant_typeSpecifies which grant type to use in the OAuth 2.0 web flow. Set this to authorization_code.
scopeDetermines the level of access your partner OAuth application has to the merchant's account. Set this to payments.
redirect_uriPer the OAuth 2.0 specification, this is the URI to which the AffiniPay web application will redirect after successful authorization. Your web server must handle redirects to this URI according to the OAuth 2.0 specification.
codeThe authorization_code that the Authentication API sends to the redirect URI you specified in your partner OAuth application after a user logs in and authorizes your application.
Example request
curl -X POST -H "Content-Type:application/json" https://api.affinipay.com/oauth/token -d '
{
  "client_id":"Y4QLWPO6wZag2ia8Abw7nbeLUAOgebDlfZGF1KyzgBaqAllzMtYFfP58jRxg5rp5",
  "client_secret":"4EG357enIs4m2SWKi9yfC3fQzIeOZmBTWr96ay47tqN4GUtRPYrWwxwCxwlZJbiC",
  "grant_type":"authorization_code",
  "scope":"payments",
  "redirect_uri":"http://localhost:9292/callback",
  "code":"EiKvFkJu6rcFwOMWSqW8bWIng6EMFVD93duwn1QhgQKDvmpbA97zWFN2AfC5052R"
}'
Example response
{
  "access_token":"Msp2VL7SEGbLxT8UBWww7WUy33hLsg5Yhf5fFu8znSpPh2BbBMvXPyQkZx5TtWHd",
  "token_type":"bearer",
  "scope":"payments",
  "created_at":1464986958
}

Gateway Credentials

Request Gateway Credentials

GET /gateway-credentials

This endpoint returns a list of the test and live accounts associated with the authenticated user’s merchant account. Included in this information are the necessary keys for making calls to the AffiniPay Payment Gateway API. Save these credentials securely so your partner OAuth application can manage transactions on behalf of merchant users.

Example request
curl -X GET -H "Authorization: Bearer <access_token>" https://api.affinipay.com/gateway-credentials
Example response
{
    "application": "Example App",
    "user": {
        "first_name": "Dave",
        "last_name": "Bowman",
        "email": "dave@example.com",
        "owner": true,
        "abilities": [
            "admin",
            "charge",
            "schedule_charge",
            "refund",
            "tag_transactions",
            "view_reports"
        ]
    },
    "merchant": {
        "name": "Acme Inc.",
        "address": "123 Main Street",
        "additional_address": "Suite 300",
        "city": "Austin",
        "state": "TX",
        "postal_code": "02360",
        "country": "US",
        "phone": "9789879878",
        "timezone": "Eastern Time (US & Canada)",
        "website": "http://www.example.com",
        "support_email": "support@example.com",
        "support_phone": "(978) 987-9878",
        "email_success_to": "admin@example.com",
        "email_failure_to": "admin@example.com",
        "reference_required": true,
        "reference_label": "New Reference Label Name"
    },
    "test_accounts": [
        {
            "name": "Operating",
            "type": "MerchantAccount",
            "currency": "USD",
            "recurring_charges_enabled": false,
            "id": "_DVA8TyeQ9qreE_a0vpv5w",
            "public_key": "m_7LwaBGj6T52TyR60xvjgzg",
            "secret_key": "tccsidx6bf3e15blzlbtztvkx6m2v39ulrstbg5c1fgtaykf9lyzkz9nb1fcavx",
            "trust_account": "false"
        },
        {
            "name": "Trust",
            "type": "MerchantAccount",
            "currency": "USD",
            "recurring_charges_enabled": false,
            "id": "Icw6sdURR_CGF3ch3zbfrQ",
            "public_key": "m_7LwaBGj6T52TyR60xvjgzg",
            "secret_key": "tccsidx6bf3e15blzlbtztvkx6m2v39ulrstbg5c1fgtaykf9lyzkz9nb1fcavx",
            "trust_account": "true"
        },
        {
            "name": "eCheck",
            "type": "AchAccount",
            "currency": "USD",
            "recurring_charges_enabled": false,
            "id": "P4L8ytrISoKp39xecKa_Nw",
            "public_key": "m_7LwaBGj6T52TyR60xvjgzg",
            "secret_key": "tccsidx6bf3e15blzlbtztvkx6m2v39ulrstbg5c1fgtaykf9lyzkz9nb1fcavx",
            "trust_account": "false"
        }
    ],
    "live_accounts": []
}

Deauthorize an OAuth Application

DELETE /merchants/{merchant_public_key}/deauthorize_application

Revoke authorization to use a partner OAuth application from the specified AffiniPay merchant account. This call requires you to obtain an access token using the OAuth client credentials flow.

ParameterDescription
public_keyA unique 24-character, alphanumeric string used to identify AffiniPay merchant accounts.
access_tokenA unique 64-character, alphanumeric string used to identify a partner OAuth application in OAuth 2.0 web flows.
Example request
curl -X DELETE -H "Authorization: Bearer <access_token>" https://secure.affinipay.com/api/v1/merchants/{public_key}/deauthorize_application
Example response
Returns an HTTP 200 OK status code and an empty response body
when successful.

Merchant Application API

Overview

Use this API to help users sign up for AffiniPay merchant accounts or to revoke authorization to use a partner OAuth application from an existing AffiniPay merchant account.

There are two ways to get your clients to apply as an AffiniPay merchant.

Create a New Application

POST /merchant_applications

Create a new merchant_application object and submit it to AffiniPay for review and approval.

Note: All parameter values included in a request must be in plain text format. This API doesn't accept encoded values.

The request URL must correspond to the product you are integrating into your application.

  • For AffiniPay: https://secure.affinipay.com/api/v1/merchant_applications
  • For ClientPay: https://secure.clientpay.com/api/v1/merchant_applications
  • For CPACharge: https://secure.cpacharge.com/api/v1/merchant_applications
  • For LawPay: https://secure.lawpay.com/api/v1/merchant_applications

The example shows a merchant application submitted for AffiniPay.

Note: You should submit test applications with the test attribute before submitting real applications.

Example request
curl -X POST -H "Content-Type:application/json" -H "Authorization: Bearer <access_token>" https://secure.affinipay.com/api/v1/merchant_applications
{
  "merchant_application": {
      "plan": "partner_specific_plan_id",
      "first_name": "Dave",
      "last_name": "Bowman",
      "email": "dave@example.com",
      "business_name": "Example Company",
      "structure": "SO",
      "business_address1": "123 Main St",
      "business_city": "Austin",
      "business_zip_code": "78780",
      "business_phone": "5122232342",
      "industry_code": "9311",
      "federal_tax_id": "123456789",
      "years_in_business": "5",
      "business_state": "TX",
      "goods_and_services": "Goods and services Description",
      "owner_email": "owner@example.com",
      "owner_first_name": "Owner",
      "owner_last_name": "APIMerchant",
      "owner_title": "Owner",
      "owner_date_of_birth": "1989-03-14",
      "owner_address1": "1050 Spicewood Springs",
      "owner_city": "Austin",
      "owner_state": "TX",
      "owner_zip_code": "78792",
      "owner_years_in_residence": "2",
      "owner_phone_number": "5123212356",
      "owner_social_security_number": "232835746",
      "owner_drivers_license_number": "284729257",
      "owner_drivers_license_state": "TX",
      "owner_drivers_license_expiration": "2020-03-30",
      "operating_account_name": "Test Account",
      "operating_account_routing_number": "000000013",
      "operating_account_bank_name": "Test Bank",
      "operating_account_number": "1000000001",
      "signed_by": "Owner",
      "signature": "[{\"lx\":97,\"ly\":162,\"mx\":97,\"my\":161},
                    {\"lx\":99,\"ly\":157,\"mx\":97,\"my\":162},
                    {\"lx\":105,\"ly\":149,\"mx\":99,\"my\":157},
                    {\"lx\":114,\"ly\":139,\"mx\":105,\"my\":149},
                    {\"lx\":131,\"ly\":121,\"mx\":114,\"my\":139},
                    {\"lx\":154,\"ly\":97,\"mx\":131,\"my\":121},
                    {\"lx\":182,\"ly\":72,\"mx\":154,\"my\":97},
                    {\"lx\":199,\"ly\":56,\"mx\":182,\"my\":72},
                    {\"lx\":208,\"ly\":51,\"mx\":199,\"my\":56},
                    {\"lx\":211,\"ly\":50,\"mx\":208,\"my\":51},
                    {\"lx\":213,\"ly\":52,\"mx\":211,\"my\":50},
                    {\"lx\":217,\"ly\":62,\"mx\":213,\"my\":52},
                    {\"lx\":224,\"ly\":79,\"mx\":217,\"my\":62},
                    {\"lx\":233,\"ly\":96,\"mx\":224,\"my\":79},
                    {\"lx\":248,\"ly\":119,\"mx\":233,\"my\":96},
                    {\"lx\":260,\"ly\":134,\"mx\":248,\"my\":119},
                    {\"lx\":279,\"ly\":148,\"mx\":260,\"my\":134},
                    {\"lx\":293,\"ly\":151,\"mx\":279,\"my\":148},
                    {\"lx\":310,\"ly\":153,\"mx\":293,\"my\":151},
                    {\"lx\":330,\"ly\":148,\"mx\":310,\"my\":153},
                    {\"lx\":351,\"ly\":141,\"mx\":330,\"my\":148},
                    {\"lx\":379,\"ly\":127,\"mx\":351,\"my\":141},
                    {\"lx\":401,\"ly\":112,\"mx\":379,\"my\":127},
                    {\"lx\":420,\"ly\":93,\"mx\":401,\"my\":112},
                    {\"lx\":436,\"ly\":75,\"mx\":420,\"my\":93},
                    {\"lx\":449,\"ly\":57,\"mx\":436,\"my\":75},
                    {\"lx\":458,\"ly\":45,\"mx\":449,\"my\":57},
                    {\"lx\":461,\"ly\":38,\"mx\":458,\"my\":45},
                    {\"lx\":462,\"ly\":35,\"mx\":461,\"my\":38},
                    {\"lx\":460,\"ly\":35,\"mx\":462,\"my\":35},
                    {\"lx\":449,\"ly\":38,\"mx\":460,\"my\":35},
                    {\"lx\":419,\"ly\":53,\"mx\":449,\"my\":38},
                    {\"lx\":392,\"ly\":69,\"mx\":419,\"my\":53},
                    {\"lx\":357,\"ly\":96,\"mx\":392,\"my\":69},
                    {\"lx\":334,\"ly\":117,\"mx\":357,\"my\":96},
                    {\"lx\":298,\"ly\":142,\"mx\":334,\"my\":117},
                    {\"lx\":264,\"ly\":162,\"mx\":298,\"my\":142},
                    {\"lx\":234,\"ly\":173,\"mx\":264,\"my\":162},
                    {\"lx\":208,\"ly\":177,\"mx\":234,\"my\":173},
                    {\"lx\":193,\"ly\":178,\"mx\":208,\"my\":177},
                    {\"lx\":178,\"ly\":178,\"mx\":193,\"my\":178},
                    {\"lx\":165,\"ly\":176,\"mx\":178,\"my\":178},
                    {\"lx\":151,\"ly\":175,\"mx\":165,\"my\":176},
                    {\"lx\":140,\"ly\":173,\"mx\":151,\"my\":175},
                    {\"lx\":133,\"ly\":172,\"mx\":140,\"my\":173},
                    {\"lx\":130,\"ly\":171,\"mx\":133,\"my\":172},
                    {\"lx\":128,\"ly\":170,\"mx\":130,\"my\":171},
                    {\"lx\":126,\"ly\":166,\"mx\":128,\"my\":170},
                    {\"lx\":125,\"ly\":162,\"mx\":126,\"my\":166},
                    {\"lx\":122,\"ly\":152,\"mx\":125,\"my\":162},
                    {\"lx\":119,\"ly\":143,\"mx\":122,\"my\":152},
                    {\"lx\":116,\"ly\":127,\"mx\":119,\"my\":143},
                    {\"lx\":115,\"ly\":115,\"mx\":116,\"my\":127},
                    {\"lx\":113,\"ly\":99,\"mx\":115,\"my\":115},
                    {\"lx\":113,\"ly\":87,\"mx\":113,\"my\":99},
                    {\"lx\":112,\"ly\":81,\"mx\":113,\"my\":87},
                    {\"lx\":113,\"ly\":78,\"mx\":112,\"my\":81},
                    {\"lx\":114,\"ly\":78,\"mx\":113,\"my\":78},
                    {\"lx\":117,\"ly\":78,\"mx\":114,\"my\":78},
                    {\"lx\":128,\"ly\":82,\"mx\":117,\"my\":78},
                    {\"lx\":151,\"ly\":95,\"mx\":128,\"my\":82},
                    {\"lx\":174,\"ly\":107,\"mx\":151,\"my\":95},
                    {\"lx\":211,\"ly\":121,\"mx\":174,\"my\":107},
                    {\"lx\":238,\"ly\":130,\"mx\":211,\"my\":121},
                    {\"lx\":271,\"ly\":136,\"mx\":238,\"my\":130},
                    {\"lx\":295,\"ly\":139,\"mx\":271,\"my\":136},
                    {\"lx\":333,\"ly\":143,\"mx\":295,\"my\":139},
                    {\"lx\":371,\"ly\":146,\"mx\":333,\"my\":143},
                    {\"lx\":398,\"ly\":147,\"mx\":371,\"my\":146},
                    {\"lx\":420,\"ly\":146,\"mx\":398,\"my\":147},
                    {\"lx\":434,\"ly\":142,\"mx\":420,\"my\":146},
                    {\"lx\":451,\"ly\":135,\"mx\":434,\"my\":142},
                    {\"lx\":463,\"ly\":128,\"mx\":451,\"my\":135},
                    {\"lx\":472,\"ly\":123,\"mx\":463,\"my\":128},
                    {\"lx\":475,\"ly\":120,\"mx\":472,\"my\":123},
                    {\"lx\":476,\"ly\":118,\"mx\":475,\"my\":120},
                    {\"lx\":476,\"ly\":116,\"mx\":476,\"my\":118},
                    {\"lx\":477,\"ly\":116,\"mx\":476,\"my\":116}]",
      "ip_address": "76.103.150.128",
      "browser_user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36",
      "browser_language": "en-US,en;q=0.9,it;q=0.8,es;q=0.7,la;q=0.6",
      "ip_address_timestamp": "2019-09-17T18:49:32Z",
      "reference": "1hhta8u1"
  }
}
Example response
{
    "merchant_application": {
        "id": "12234"
    }
}

Start the Sign-Up Flow

POST /merchant_applications/sign_up

For additional information, see the related developer documentation.

Create a new merchant_application object using the branded sign-up flow and submit it to AffiniPay for review and approval.

The request URL must correspond to the product you are integrating into your application.

  • For AffiniPay: https://secure.affinipay.com/api/v1/merchant_applications/sign_up
  • For ClientPay: https://secure.clientpay.com/api/v1/merchant_applications/sign_up
  • For CPACharge: https://secure.cpacharge.com/api/v1/merchant_applications/sign_up
  • For LawPay: https://secure.lawpay.com/api/v1/merchant_applications/sign_up

The following parameters are required.

Note: All parameter values included in a request must be in plain text format. This API doesn't accept encoded values.

ParameterTypeDescription
referencestringThe unique ID for the user in the partner's system.
emailstringThe user's email.
planstringThe identifier for your plan within the AffiniPay system. We will create this plan for you and provide you the correct ID to use.

Note: To test merchant applications submitted using this endpoint and the sign-up flow, follow the testing instructions.

The following parameters are optional. If they are included, they will be used to populate the sign-up flow so the user doesn't have to enter this information themselves.

ParameterTypeDescription
first_namestringFirst name of the person associated with the merchant application.
last_namestringLast name of the person associated with the merchant application.
business_namestringThe business's legal name. This must match what is on record with the IRS.
business_address1stringThe business's mailing address.
business_address2stringAdditional address field.
business_citystringThe city where the business is located.
business_statestringThe state where the business is located.
business_zip_codestringThe business's postal ZIP code.
business_phonestringThe business's primary contact number.
business_countrystringThe 2-letter ISO 3166 country code for the country where the business is located.
industry_codeintegerThe business's Standard Industrial Classification (SIC) code (e.g., 8111 – Legal Services).
goods_and_servicesstringSend "Legal Fees" for a LawPay integration. Contact AffiniPay for the correct string to use for other integrations.
has_dbabooleanIndicates whether a Doing Business As (DBA) name has been registered for the business; default is false (optional).
dba_namestringThe business's registered Doing Business As (DBA) name (optional if has_dba is false).
dba_address1stringThe mailing address of the business with a registered Doing Business As (DBA) name (optional if has_dba is false).
dba_address2stringAdditional address field (optional if has_dba is false).
dba_citystringThe city where the business with a registered Doing Business As (DBA) name is located (optional if has_dba is false).
dba_statestringThe state where the business with a registered Doing Business As (DBA) name is located (two-letter state code) (optional if has_dba is false).
dba_zip_codestringThe postal ZIP code of the business with a registered Doing Business As (DBA) name (optional if has_dba is false).
dba_phonestringThe primary contact number of the business with a registered Doing Business As (DBA) name (optional if has_dba is false).
structurestringThe business's structure. Accepts a 1- or 2-letter abbreviation. Only include the abbreviation in the request, not the description (e.g., SO):
  • SO – Sole Proprietor
  • AE – Assoc / Estate / Trust
  • G – Government
  • CP – Private Corporation
  • CU – Public Corporation
  • P – Partnership
  • TE – Tax Exempt
  • SM – Single Member LLC
  • MM – Multi Member LLC
  • CA – Civic Association
  • LP – Limited Partner
  • PO – Political Organization
business_typestringThe type of industry in which the business engages. Accepts a 1-letter abbreviation. Only include the abbreviation in the request, not the description (e.g., R):
  • R – Retail
  • I – Internet
  • M – Mail Order
  • H – Lodging/Hotel
  • F – Restaurant
years_in_businessstringNumber years the business has been in operation.
business_websitestringThe business's website (optional).
past_bankruptcybooleanIndicates whether the business has been through bankruptcy proceedings in the past (optional).
bankruptcy_datedateThe date the bankruptcy was finalized (optional).
owner_first_namestringThe business owner's legal first name.
owner_last_namestringThe business owner's legal last name.
owner_titlestringThe business owner's title. Accepts the following values (no spaces):
  • President
  • V.President
  • Owner
  • Partner
  • Manager
  • Treasurer
  • Secretary
  • Exec.Director
owner_percentage_of_ownershipintegerThe business owner's percentage of ownership (optional, defaults to 100).
owner_has_significant_ownershipBooleanWhether the business owner has more than 25% ownership of the business.
owner_has_significant_responsibilityBooleanWhether the business owner has significant management responsibility for the business. If no one owns more than 25% of the business, this field must be set to true for at least one owner.
owner_address1stringThe business owner's mailing address.
owner_address2stringAdditional address field.
owner_citystringThe city where the business owner lives.
owner_statestringThe state where the business owner lives.
owner_zip_codestringThe business owner's postal ZIP code.
owner_phone_numberstringThe business owner's primary contact number.
owner_emailstringThe business owner's email address.
owner_years_in_residenceintegerThe number of years the business owner has resided at owner_address1 (optional).
owner_country_of_citizenshipstringThe 2-letter ISO 3166 country code for the country where the business owner resides.
Example request
curl -X POST -H "Content-Type:application/json" -H "Authorization: Bearer <access_token>" https://secure.affinipay.com/api/v1/merchant_applications/sign_up
{
  "reference": "1941",
  "email": "diana@example.com",
  "plan": "superplan"
}
Example response
{
    "merchant_application": {
        "id": 1941
    },
    "redirect_uri": "https://secure.affinipay.com/sso/merchant_applications/registrations?token=512...>"
}

Object Types

All request and response content in this API use JSON representations. This section describes the properties, data types, and constraints of each of the object types present in the API.

  • Boolean. Boolean values are represented using the JSON literal values true and false.
  • Date. Date values (with no time component) are represented using the format yyyy-mm-dd.

merchant_application

Provides all the details necessary to sign up a user for an AffiniPay merchant account.

Note: All parameter values included in a request must be in plain text format. This API doesn't accept encoded values.

ParameterTypeDescription
referencestringThis is the value your system generates to identify the merchant application. The Event URL you specify in your partner OAuth application plus this parameter equals the URL to which AffiniPay will send the event. (e.g., https://app.partner.com/<reference_ID>)
planstringThe identifier for your plan within the AffiniPay system. We will create this plan for you and provide you the correct ID to use.
first_namestringFirst name of the person associated with the merchant application.
last_namestringLast name of the person associated with the merchant application.
emailstringEmail address of the person associated with the merchant application.
business_namestringThe business's legal name. This must match what is on record with the IRS.
business_address1stringThe business's mailing address.
business_address2stringAdditional address field.
business_citystringThe city where the business is located.
business_statestringThe state where the business is located.
business_zip_codestringThe business's postal ZIP code.
business_phonestringThe business's primary contact number.
business_countrystringThe 2-letter ISO 3166 country code for the country where the business is located.
industry_codeintegerThe business's Standard Industrial Classification (SIC) code (e.g., 8111 – Legal Services).
goods_and_servicesstringSend "Legal Fees" for a LawPay integration. Contact AffiniPay for the correct string to use for other integrations.
has_dbabooleanIndicates whether a Doing Business As (DBA) name has been registered for the business; default is false (optional).
dba_namestringThe business's registered Doing Business As (DBA) name (optional if has_dba is false).
dba_address1stringThe mailing address of the business with a registered Doing Business As (DBA) name (optional if has_dba is false).
dba_address2stringAdditional address field (optional if has_dba is false).
dba_citystringThe city where the business with a registered Doing Business As (DBA) name is located (optional if has_dba is false).
dba_statestringThe state where the business with a registered Doing Business As (DBA) name is located (two-letter state code) (optional if has_dba is false).
dba_zip_codestringThe postal ZIP code of the business with a registered Doing Business As (DBA) name (optional if has_dba is false).
dba_phonestringThe primary contact number of the business with a registered Doing Business As (DBA) name (optional if has_dba is false).
structurestringThe business's structure. Accepts a 1- or 2-letter abbreviation. Only include the abbreviation in the request, not the description (e.g., SO):
  • SO – Sole Proprietor
  • AE – Assoc / Estate / Trust
  • G – Government
  • CP – Private Corporation
  • CU – Public Corporation
  • P – Partnership
  • TE – Tax Exempt
  • SM – Single Member LLC
  • MM – Multi Member LLC
  • CA – Civic Association
  • LP – Limited Partner
  • PO – Political Organization
business_typestringThe type of industry in which the business engages. Accepts a 1-letter abbreviation. Only include the abbreviation in the request, not the description (e.g., R):
  • R – Retail
  • I – Internet
  • M – Mail Order
  • H – Lodging/Hotel
  • F – Restaurant
federal_tax_idstringThe business's Federal Tax ID or the sole proprietor's Social Security Number (SSN). This must match the legal name on record with the IRS.
years_in_businessstringNumber years the business has been in operation.
business_websitestringThe business's website (optional).
past_bankruptcybooleanIndicates whether the business has been through bankruptcy proceedings in the past (optional).
bankruptcy_datedateThe date the bankruptcy was finalized (optional).
owner_first_namestringThe business owner's legal first name.
owner_last_namestringThe business owner's legal last name.
owner_titlestringThe business owner's title. Accepts the following values (no spaces):
  • President
  • V.President
  • Owner
  • Partner
  • Manager
  • Treasurer
  • Secretary
  • Exec.Director
owner_date_of_birthdateThe business owner's date of birth.
owner_social_security_numberstringThe business owner's Social Security Number (SSN); used for credit check.
owner_percentage_of_ownershipintegerThe business owner's percentage of ownership (optional, defaults to 100).
owner_has_significant_ownershipBooleanWhether the business owner has more than 25% ownership of the business.
owner_has_significant_responsibilityBooleanWhether the business owner has significant management responsibility for the business. If no one owns more than 25% of the business, this field must be set to true for at least one owner.
owner_address1stringThe business owner's mailing address.
owner_address2stringAdditional address field.
owner_citystringThe city where the business owner lives.
owner_statestringThe state where the business owner lives.
owner_zip_codestringThe business owner's postal ZIP code.
owner_phone_numberstringThe business owner's primary contact number.
owner_emailstringThe business owner's email address.
owner_years_in_residenceintegerThe number of years the business owner has resided at owner_address1 (optional).
owner_drivers_license_numberstringThe business owner's driver's license number; used to verify identity.
owner_drivers_license_statestringThe state that issued the business owner's driver's license (two-letter state code).
owner_drivers_license_expirationdateThe business owner's driver's license expiration date.
owner_country_of_citizenshipstringThe 2-letter ISO 3166 country code for the country where the business owner resides.
operating_account_namestringThe name of the business's operating account (optional).
operating_account_routing_numberstringThe routing number of the business's operating account.
operating_account_bank_namestringThe name of the bank where the business holds an operating account.
operating_account_numberstringThe business's operating account number.
trust_account_namestringThe name of the business's trust account (optional).
trust_account_routing_numberstringThe routing number of the business's trust account; optional unless plan is a trust plan (optional unless plan is a trust plan).
trust_account_bank_namestringThe name of the bank where the business holds a trust account; optional unless plan is a trust plan (optional unless plan is a trust plan).
trust_account_numberstringThe business's trust account number; optional unless plan is a trust plan (optional unless plan is a trust plan).
signed_bystringThe name of a business representative who's authorized to sign the merchant application; optional unless plan is a trust plan.
signaturestringThe signature of an authorized business representative. Uses default jQuery.signaturePad JSON format. Example: "[{"lx":5,"ly":51,"mx":5,"my":50}, {"lx":5,"ly":49,"mx":5,"my":51}]"
ip_addressstringThe merchant's browser IP address, collected at signature time. This parameter enables AffiniPay to catch fraudulent activity and perform quicker underwriting fraud checks. (optional)
browser_user_agentstringThe merchant's browser "User Agent" request header, collected at signature time. This parameter enables AffiniPay to catch fraudulent activity and perform quicker underwriting fraud checks. (optional)
browser_languagestringThe merchant's browser "Accept Language" request header, collected at signature time. This parameter enables AffiniPay to catch fraudulent activity and perform quicker underwriting fraud checks. (optional)
ip_address_timestamptimestampThe signature timestamp, collected at signature time.
teststringDefines whether the merchant application is in test mode, which you should use until you’re ready to process live merchant applications. Valid values are validate and fail. NOTE: This parameter is for use with the /merchant_applications endpoint only. To test merchant applications submitted using the /merchant_applications/sign_up endpoint and sign-up flow, follow the testing instructions.(optional)
In addition, a merchant_application can have one or more additional business_owners, configured in an array with the following parameters.
ParameterTypeDescription
first_namestringFirst name of business owner.
last_namestringLast name of business owner.
home_address1stringThe business owner's mailing address.
home_address2stringAdditional address information (optional).
home_citystringThe business owner's city.
home_statestringThe business owner's state.
home_zip_codestringThe business owner's postal ZIP code.
job_titlestringThe business owner's title. Accepts the following values (no spaces):
  • President
  • V.President
  • Owner
  • Partner
  • Manager
  • Treasurer
  • Secretary
  • Exec.Director
date_of_birthdateThe business owner's date of birth.
social_security_numberstringThe business owner's Social Security Number (SSN); used for credit check.
has_significant_ownershipBooleanWhether the business owner has more than 25% ownership of the business.
has_significant_responsibilityBooleanWhether the business owner has significant management responsibility for the business. If no one owns more than 25% of the business, this field must be set to true for at least one owner.

Messages and Errors

Any valid HTTP response codes may be returned, but an HTTP 422 (Unprocessable Entity) may be returned if the request was valid but contained invalid data. Here's an example of a 422 response body:

Example response
{
    "messages": [
        {
            "code":"invalid_data",
            "context":"trust_account_number",
            "level":"error",
            "message":"Trust account number is invalid"
        }
    ]
}

Webhooks

The AffiniPay Merchant Application API is designed to send out notifications via HTTP POST when certain events occur, like when a merchant application is approved and provisioned. A webhook is a method of subscribing to these events, so that your application can respond accordingly when it receives an event notification.

Configure Webhooks

Configuring webhooks requires two components:

  • Specify an event URL in your AffiniPay partner OAuth application
  • Configure your server to handle webhooks

Specify an Event URL

To specify where you want AffiniPay to send events:

  1. Log in to https://secure.affinipay.com/login.
  2. Click your name in the upper-right corner to open the drop-down menu and click Developers.
  3. The My Partner Applications section on the right lists your partner OAuth applications. Locate your application and click Edit. Note: If you don't see any applications, contact support and ask an AffiniPay employee to create one for you.
  4. In the Event URL text field, specify where you want AffiniPay to send events.

Configure Your Server

You must configure your server to receive and respond to webhook POST requests. AffiniPay is expecting HTTP status codes in response to webhooks. If your server doesn't respond with a 200 OK message after receiving an event, AffiniPay will attempt to resend the event once every 10 minutes for a maximum of 25 attempts.

Tip: The server endpoint must correspond with the Event URL you previously specified in your AffiniPay partner OAuth application.

Event Types

This section describes event types that the Merchant Application API generates.

merchant.provisioned

The API generates this event after AffiniPay completes the underwriting process, approves the merchant application, and provisions the applicant's new merchant account. Data includes an authorization_code, which you'll need in order to request an access_token to gain authorized access to the merchant's account.

Example
{
  "events": [{
      "type":"merchant.provisioned",
      "data": {
          "auth_code":"<authorization_code>",
          "reference":"<reference>"
      }
  }]
}

merchant_application.declined

The API generates this event after AffiniPay completes the underwriting process and denies the merchant application for one of the following reasons: duplicate_application, duplicate_merchant, or other.

Note: AffiniPay can't provide any details about why a merchant application was declined. Please ask the applicant to contact AffiniPay Support for more information.

Example
{
  "events": [{
      "type":"merchant_application.declined",
      "reason": "duplicate_application",
      "data": {
          "id":"<some_merchant_application_id>",
          "reference":"<some_partner_provided_reference>"
      }
  }]
}

Payment Gateway API

Overview

The AffiniPay Payment Gateway provides a REST API to facilitate payment processing for Merchants. Our API supports both credit card payments and electronic check (eCheck) payments, which move funds electronically between banks using routing and account numbers. It uses simple URLs and proven HTTP constructs, simplifying integration with third-party applications and existing web sites. All interactions with the Gateway are carried out over a secure connection using TLS 1.2 to safeguard data contents, and all requests are authenticated using HTTP. All request and response content is formatted using JSON, including error information.

Security

All merchants are provided with a public key and test- and live-mode secret keys to use when authenticating with the Gateway. Using the test-mode secret key, you can start using the API immediately without any worry that your charges will be passed to the payment processing networks. When you're ready to start processing payments, just switch to the live-mode secret key.

All requests to the Gateway are authenticated using HTTP Basic Authentication. To authenticate, you provide either your test- or live-mode secret key in the HTTP Authorization header.

Note: In each request, be sure to always base64-encode the public or secret key plus a trailing colon. For example, if your public key is: m_cSiyNUh9RBWHfdbFRFGrkA, you'll base64-encode m_cSiyNUh9RBWHfdbFRFGrkA:. The result is bV9jU2l5TlVoOVJCV0hmZGJGUkZHcmtBOg==, which you'll use in your request header.

curl --user secret_key: https://api.affinipay.com/...

Using the curl command line tool used in the API examples, you set this header using the --user flag, followed by the secret key, and then a trailing colon (:).

Your secret keys provide access to sensitive operations affecting payments, and therefore must be closely guarded. These keys should never be exposed in any publicly-accessible web pages, JavaScript, etc. If you suspect your test- or live-mode secret keys have been compromised, contact your Gateway account provider immediately to reset your secret keys.

In order to protect sensitive information, including your credentials and the contents of API requests and responses, the Gateway only accepts encrypted communications using HTTPS. Requests made over unsecured HTTP communications are not accepted.

Test vs Live Mode

The secret key you specify when making an API request affects how the operation is processed. The test-mode secret key only allows you to create new charges and other transactions against TEST merchant bank accounts, while the live-mode secret key only works in conjunction with merchant bank accounts associated with live payment processing networks. Attempts to mix secret keys and merchant bank accounts will fail.

Similarly, the secret key you provide filters the transactions you see when searching or retrieving specific transactions. The test-mode secret key only returns transactions created against TEST merchant bank accounts, and the live-mode secret key only returns transactions submitted to the payment processing networks.

Restricting Client Access

In order to help prevent fraudulent access and charging, the Gateway provides policy configuration options to Merchants for the API as a whole, as well as on a per-Account basis for transactions. At the API level, Merchants can restrict access to clients with IP addresses in a defined set of ranges. For example, a Merchant that accesses the Gateway via an intermediate application (for example, a hosted web-based application) can set their configuration to restrict the API from accepting requests from any other sources. The IP address restrictions are configured by setting the api_allowed_ip_address_ranges property on the Merchant.

The countries from which transaction operations (Authorize, Void, Capture, Refund, and Credit) are allowed may also be restricted to specific countries. Countries are determined by performing a geographic lookup by IP address. Country restrictions are enforced on a per-Account basis via the transaction_allowed_countries property.

Depending on the Merchant's integration with the Gateway, transaction operations may be performed from by different users, from different IP address ranges. For example, a Merchant that manually runs customer transactions from a partner application that interacts with the Gateway could simply lock API access to the partner application and restrict transaction operations to the country in which the Merchant resides.

Another common scenario is for the Merchant to expose a web-based payment form to customers, perhaps integrated with shopping cart functionality, such that charges are performed by the Merchant's customers instead. In this case, the customer's IP address must be checked against the country restrictions rather than the application server making requests to the Gateway on behalf of those customers.

In order to preserve the ability to perform client IP address checks in this scenario, the Gateway supports an optional HTTP header X-Relayed-IP-Address in requests. The value of this header is the actual customer IP address on behalf of which the merchant application is making the API request. When the Gateway observes this header in an API request, it first checks that the request's actual IP address (i.e., the merchant application) originates from an address in the Merchant's api_allowed_ip_address_ranges list. If the list is empty, or the address matches one of the configured ranges, the request is accepted and the relayed IP address is used for country-based policy checks.

You can test relaying IP addresses against Merchant client restrictions by modifying the curl command line as follows:

curl -H "X-Relayed-IP-Address: 127.0.0.1" ...

Responses and Errors

The Gateway REST APIs return standard HTTP status codes to indicate the success or failure of each operation. Status codes in the 2xx family indicate success, the 4xx family indicates a failure stemming from the data provided in the request, and the 5xx family indicates the Gateway failed to process the request for reasons outside the caller's control.

API responses that indicate successful completion may contain JSON content in the response body, as defined by the API contract. In the case of an error status, the response body will typically contain JSON content providing details of the problem. Refer to Messages and Errors for a detailed list of the types of errors and their contents.

Response CodeDescription
200The operation succeeded
204The operation succeeded, but no response content was returned (normal for APIs that do not return any JSON response)
400The request was malformed
401Authentication credentials were not provided, or were not valid for the requested operation
404An item referred to in the request, such as a charge or merchant bank account, was not found
422The request could not be processed. This is typically due to validation errors reported in the response.
500An error occurred on the Gateway while processing the request

Testing

Before you put your integration to the Gateway into production use, you should test each of the APIs you use with a variety of valid and invalid request data to exercise both success and failure scenarios in your application.

Test Card Numbers

Successful charges can be created using the following card numbers in conjunction with the test-mode secret key and a card expiration in the future:

Card NumberCard Type
378282246310005American Express
371449635398431American Express
5105105105105100MasterCard
5499740000000057MasterCard
30569309025904Diners Club
38520000023237Diners Club
6011000990139424Discover
3530111333300000JCB
3566002020360505JCB
4242424242424242Visa
4012888888881881Visa
4400000000000008Visa Debit

Failure scenarios can be tested using the following card numbers and the test-mode secret key:

Card NumberError Code
4000000000000002card_declined
4000000000000044card_declined_insufficient_funds
4000000000000051card_declined_limit_exceeded
4000000000000069card_expired
4000000000000119card_declined_processing_error
4000000000000127card_declined_hold
4242424242424241card_number_invalid
4000000000000135card_type_not_accepted
6011111111111117503 PROCESSOR NOT AVAILABLE
5555555555554444500 SERVER ERROR

CVV and AVS checks can be tested against various account policies using the following card numbers and the test-mode secret key. Note that depending on the policy in effect, the CVV and AVS results may or may not result in an error code being returned. For example, if the CVV policy is set to DISABLED, a CVV Not Matched response will not cause a failure, whereas it would if the CVV policy were set to REQUIRE_MATCH_LENIENT.

Card NumberCVV/AVS Response
4000000000000077CVV Unavailable
4000000000000101CVV Not Matched
4000000000000010AVS Not Matched
4000000000000085AVS Unavailable
4000000000000093AVS Error
4000000000000028If card postal code is null or empty, AVS returns Not Matched. Otherwise, an AVS Postal Code Match is returned.
4000000000000036If card address is null or empty, AVS returns Not Matched. Otherwise an AVS Address Match is returned.

Test Bank Account Numbers

Using a TEST bank account, you can capture eCheck transfers using the routing numbers 000000000 or 000000013 with any account number. The following exceptions return eCheck errors useful for testing purposes:

Routing NumberAccount NumberError Code
0000000131000000001ach_declined
0000000131000000002ach_declined_hold
0000000131000000003ach_declined_duplicate
0000000131000000004ach_invalid_account_number
0000000131000000005ach_insufficient_funds
0000000131000000006ach_account_not_found
0000000131000000007ach_account_closed
0000000131000000008ach_account_frozen
0000000131000000009ach_limit_exceeded
000000001Anyach_invalid_routing_number
0000000131000000004422 INVALID ACCOUNT NUMBER
0000000131000000011503 ACH PROCESSOR NOT AVAILABLE
0000000131000000012500 SERVER ERROR

System Status

GET /status

Integrating systems can retrieve the current status of the Gateway by issuing a GET request to /status. The operation returns an enumeration indicating the basic status, as detailed in the table below. This operation, which requires no authentication, can be used to check connectivity to the Gateway as well as to identify potential problems that may impact payment processing.

StatusDescription
NORMALThe gateway is functioning normally.
EXCESSIVE_LATENCYAPI request durations are exceeding expected thresholds.
SERVICE_UNRELIABLERecent intermittent failures are impacting payment processing.
SERVICE_UNAVAILABLEThe system us experiencing problems that prevent payment processing.

Example Request

curl https://api.affinipay.com/status

Example Response

{
  "status":"NORMAL"
}

Merchant Management

The gateway provides the following operations for Merchants to retrieve and update their business information, as well as update the details, policy, and status of merchant_accounts and ach_accounts.

Get Current Merchant

GET /v1/merchant

Returns the currently-authenticated merchant. This operation can be used to test authenticating to the Gateway using a Merchant's credentials. Note that the merchant and eCheck accounts returned are filtered based on whether a live or test-mode secret key was provided. Only TEST accounts are returned if a test-mode secret key is used, while a live-mode secret key only returns live accounts.

Example request
curl -X GET --user secret_key: https://api.affinipay.com/v1/merchant
Example response
{
      "id": "wKgFeDz5HF-BPPl08dcACw",
      "created": "2018-05-29T17:51:19.592Z",
      "modified": "2019-09-30T13:02:33.981Z",
      "name": "Biz1",
      "public_key": "m_wKgFeD0hHlaBPSGgaAQAAA",
      "contact_name": "Merchant Contact",
      "contact_email": "admin@example.com",
      "contact_phone": "9876543210",
      "address1": "97 Hammond St",
      "city": "Bangor",
      "state": "ME",
      "postal_code": "04401",
      "country": "US",
      "timezone": "America/New_York",
      "api_allowed_ip_address_ranges": "127.0.0.1/32,198.51.100.1/24",
      "merchant_accounts": [
          {
              "id": "wKgFeDz5HF-BPPl08dcADQ",
              "created": "2018-06-05T16:42:42.735Z",
              "modified": "2018-10-08T16:51:04.889Z",
              "status": "ACTIVE",
              "trust_account": false,
              "currency": "USD",
              "name": "Operating",
              "primary": true,
              "required_payment_fields": "name",
              "cvv_policy": "REQUIRE_MATCH_LENIENT",
              "avs_policy": "ADDR_OR_POSTAL_CODE_LENIENT",
              "ignore_avs_failure_if_cvv_match": false,
              "swipe_cvv_policy": "DISABLED",
              "swipe_avs_policy": "DISABLED",
              "swipe_ignore_avs_failure_if_cvv_match": false,
              "transaction_allowed_countries": "US,CA"
          }, {
              "id": "wKgFeDz5HF-BPPl08dcADA",
              "created": "2018-05-29T17:53:07.143Z",
              "modified": "2019-10-19T04:02:23.019Z",
              "status": "ACTIVE",
              "trust_account": true,
              "currency": "USD",
              "name": "Trust",
              "primary": false,
              "required_payment_fields": "name",
              "cvv_policy": "REQUIRE_MATCH_LENIENT",
              "avs_policy": "ADDR_OR_POSTAL_CODE_LENIENT",
              "ignore_avs_failure_if_cvv_match": false,
              "swipe_cvv_policy": "DISABLED",
              "swipe_avs_policy": "DISABLED",
              "swipe_ignore_avs_failure_if_cvv_match": false,
              "transaction_allowed_countries": "US,CA"
          }
      ],
      "ach_accounts": [
          {
              "id": "5A299P9oEeKcOfUBJK8FBw",
              "created": "2018-06-29T18:29:28.895Z",
              "modified": "2019-10-08T16:50:06.377Z",
              "status": "ACTIVE",
              "trust_account": false,
              "name": "Test Bank Account",
              "primary": true,
              "currency": "USD",
              "required_payment_fields": "name",
              "transaction_allowed_countries": "US"
          }
      ]
  }
  

Update Merchant

PUT | PATCH /v1/merchant

A Merchant may update their merchant name, contact information, and client policy constraints by sending a PUT or PATCH request to /v1/merchant. A PUT request requires the complete contents of the merchant to be sent in the JSON request, whereas PATCH requests can send just the JSON elements that should be changed. The updated Merchant is returned.

Example request
curl -X PUT -H "Content-Type:application/json" --user secret_key: https://api.affinipay.com/v1/merchant -d '
  {
      "name": "Biz1 Updated",
      "contact_name": "Merchant Contact",
      "contact_email": "admin@biz1.com",
      "contact_phone": "9876543210",
      "address1": "97 Hammond St",
      "city": "Bangor",
      "state": "ME",
      "postal_code": "04401",
      "country": "US",
      "timezone": "America/New_York",
      "api_allowed_ip_address_ranges": "16.42.10.0/30",
      "live_events_urls": "http://merchant.example.com/events/live,http://system2.example.com/messages",
      "test_events_urls": "http://merchant.example.com/events/test"
  }'
Example response
{
      "id": "wKgFeDz5HF-BPPl08dcACw",
      "name": "Biz1 Updated",
      "public_key": "m_wKgFeD0hHlaBPSGgaAQAAA",
      "contact_name": "Merchant Contact",
      "contact_email": "admin@biz1.com",
      "contact_phone": "9876543210",
      "address1": "97 Hammond St",
      "city": "Bangor",
      "state": "ME",
      "postal_code": "04401",
      "country": "US",
      "timezone": "America/New_York",
      "api_allowed_ip_address_ranges": "16.42.10.0/30",
      "live_events_urls": "http://merchant.example.com/events/live,http://system2.example.com/messages",
      "test_events_urls": "http://merchant.example.com/events/test",
      "merchant_accounts": [
          ...
      ],
      "bank_accounts": [
          ...
      ]
  }
Example request
curl -X PATCH -H "Content-Type:application/json" --user secret_key: https://api.affinipay.com/v1/merchant -d '
  {
      "name": "My New Business Name",
  }'
Example response
{
      "id": "wKgFeDz5HF-BPPl08dcACw",
      "name": "My New Business Name",
      "public_key": "m_wKgFeD0hHlaBPSGgaAQAAA",
      "contact_name": "Merchant Contact",
      "contact_email": "admin@biz1.com",
      "contact_phone": "9876543210",
      "address1": "97 Hammond St",
      "city": "Bangor",
      "state": "ME",
      "postal_code": "04401",
      "country": "US",
      "timezone": "America/New_York",
      "api_allowed_ip_address_ranges": "16.42.10.0/30",
      "live_events_urls": "http://merchant.example.com/events/live,http://system2.example.com/messages",
      "test_events_urls": "http://merchant.example.com/events/test",
      "merchant_accounts": [
          ...
      ],
      "bank_accounts": [
          ...
      ]
  }

Update eCheck Account

PUT | PATCH /v1/ach-accounts/{accountId}

A Merchant may update the name, primary status, and policy configuration of an ach_account by sending a PUT or PATCH request to /v1/ach-accounts/{accountId}. A PUT request requires the complete contents of the ach_account to be sent in the JSON request, whereas PATCH requests can send just the JSON elements that should be changed. The updated ach_account is returned.

Example request
curl -X PUT -H "Content-Type:application/json" --user secret_key: https://api.affinipay.com.com/v1/ach-accounts/5A299P9oEeKcOfUBJK8FBw -d '
  {
      "name": "Test Bank Account",
      "primary": true,
      "required_payment_fields": "name",
      "transaction_allowed_countries": "US"
  }'
Example response
{
      "id": "5A299P9oEeKcOfUBJK8FBw",
      "status": "ACTIVE",
      "routing_number": "******013",
      "account_number": "*****8932",
      "account_type": "CHECKING",
      "bank_name": "FIRST BANK OF TESTING",
      "name": "Test Bank Account",
      "primary": true,
      "required_payment_fields": "name",
      "transaction_allowed_countries": "US"
  }
Example request
curl -X PATCH -H "Content-Type:application/json" --user secret_key: https://api.affinipay.com/v1/ach-accounts/5A299P9oEeKcOfUBJK8FBw -d '
  {
      "required_payment_fields": "name,address1,postal_code",
      "transaction_allowed_countries": "US"
  }'
Example response
{
      "id": "5A299P9oEeKcOfUBJK8FBw",
      "status": "ACTIVE",
      "routing_number": "******013",
      "account_number": "*****8932",
      "account_type": "CHECKING",
      "bank_name": "FIRST BANK OF TESTING",
      "name": "Test Bank Account",
      "primary": true,
      "required_payment_fields": "name,address1,postal_code",
      "transaction_allowed_countries": "US"
  }

Purge Test Data

POST /v1/merchant/purge-test-data

Testing your integration via our API can result in a lot of data being generated associated with your account: payment methods, transactions, recurring charges, etc. This data can sometimes make it more difficult to verify that your integration is working as expected. Using the /v1/merchant/purge-test-data endpoint, you can discard all of your test data and return to a clean slate.

Note: Live-mode data is never modified by this endpoint.

Example request
curl -X POST -H "Content-Type:application/json" --user secret_key: https://api.affinipay.com/v1/merchant/purge-test-data
Example response
Returns an HTTP 204 No Content status code and an empty response body when successful.

Transactions

The Gateway's streamlined transaction API simplifies the process of submitting payments and applying refunds to those payments. The Charge API submits a payment request using a customer's payment details. The Gateway automatically performs funds capture daily and initiates settlement. Refund can be performed up to six months after the Charge, in any number, up to the amount of the Charge.

The API also includes methods for retrieving individual transactions by ID, as well as a search operation that returns paginated results based on criteria specified by the caller.

Note: To avoid exposing credentials, always make API calls from the server, not from the browser.

Charges

POST /v1/charges

The /v1/charges API submits a payment request from a customer using the payment method included in the request. The payment method can be a card or bank or the ID of a PaymentMethod, saved card, saved bank, or one-time token. The operation performs an authorize for the funds specified and returns the Charge in the response.

To meet PCI requirements, create a payment form with hosted fields to tokenize payment details. See Creating payment forms using hosted fields.

If no account ID is specified in the request, the Gateway automatically selects the primary merchant or eCheck account, depending on the type of payment method specified; for example, providing a bank method results in the primary eCheck account being selected. If no matching account is found, or if an account ID is provided but does not match the payment method, the charge is rejected.

By default, all successful authorizations are captured automatically daily for all the Merchant's accounts at a time configured by the Merchant's Tenant. For credit card payments, separate authorization and capture can be performed by specifying auto_capture: false in the JSON request, resulting in a hold being placed on the customer's funds without automatic capture. Transactions must be captured or voided using the corresponding APIs; otherwise they are automatically voided by the Gateway after 7 days.

For information about why it is important to collect particular types of cardholder and payment details, see the related developer documentation. In addition, you can view each payment object to see which fields are required.
Creating a credit card charge using a saved payment method or one-time token
curl -X POST -H "Content-Type:application/json" --user secret_key: https://api.affinipay.com/v1/charges -d '
  {
      "amount": "100",
      "method": "RNZyuzAPTK2TSS6hPKafDA",
      "account_id": "wKgFeDz5HF-BPPl08dcADQ"
  }'
Example response
{
      "id": "wKgFnjz8GamBPPzKzIsAAA",
      "type": "CHARGE",
      "account_id": "wKgFeDz5HF-BPPl08dcADQ",
      "status": "AUTHORIZED",
      "amount": 100,
      "currency": "USD",
      "auto_capture": true,
      "amount_refunded": 0,
      "authorization_code": "RLQMEA",
      "method": {
          "type": "card",
          "number": "************4242",
          "fingerprint": "GunPelYVthifNV63LEw1",
          "card_type": "VISA",
          "exp_month": 10,
          "exp_year": 2025,
          "name": "Some Customer"
      },
      "cvv_result" : "MATCHED"
  }
  
Creating a credit card Charge with automatic capture
curl -X POST -H "Content-Type:application/json" --user secret_key: https://api.affinipay.com/v1/charges -d '
  {
      "amount": "100",
      "account_id": "wKgFeDz5HF-BPPl08dcADQ",
      "method": {
          "type": "card",
          "number": "4242424242424242",
          "exp_month": 10,
          "exp_year": 2025,
          "cvv": "123",
          "name": "Some Customer"
      }
  }'
Example response
{
      "id": "wKgFnjz8GamBPPzKzIsAAA",
      "type": "CHARGE",
      "account_id": "wKgFeDz5HF-BPPl08dcADQ",
      "status": "AUTHORIZED",
      "amount": 100,
      "currency": "USD",
      "auto_capture": true,
      "amount_refunded": 0,
      "authorization_code": "MFIADB",
      "method": {
          "type": "card",
          "number": "************4242",
          "fingerprint": "CmsP3lYV4akuOz12pFa8",
          "card_type": "VISA",
          "exp_month": 10,
          "exp_year": 2025,
          "name": "Some Customer"
      }
  }
  
Creating an authorization-only credit card Charge
curl -X POST -H "Content-Type:application/json" --user secret_key: https://api.affinipay.com/v1/charges -d '
  {
      "amount": "100",
      "auto_capture": false,
      "account_id": "wKgFeDz5HF-BPPl08dcADQ",
      "method": {
          "type": "card",
          "number": "4242424242424242",
          "exp_month": 10,
          "exp_year": 2025,
          "cvv": "123",
          "name": "Sample Customer",
          "address1": "123 Main St",
          "city": "Austin",
          "state": "TX",
          "postal_code": "78730"
      }
  }'
Example response
{
      "id": "wKgFnjz8GamBPP0ASxIABA",
      "type": "CHARGE",
      "account_id": "wKgFeDz5HF-BPPl08dcADQ",
      "status": "AUTHORIZED",
      "amount": 100,
      "currency": "USD",
      "auto_capture": false,
      "amount_refunded": 0,
      "authorization_code": "DSFCCO",
      "method": {
          "type": "card",
          "number": "************4242",
          "fingerprint": "CmsP3lYV4akuOz12pFa8",
          "card_type": "VISA",
          "exp_month": 10,
          "exp_year": 2025,
          "name": "Sample Customer",
          "address1": "123 Main St",
          "city": "Austin",
          "state": "TX",
          "postal_code": "78730"
      },
      "cvv_result" : "MATCHED",
      "avs_result" : "ADDRESS_AND_ZIP5"
  }
  
Creating a Charge debiting a customer's business bank account
curl -X POST -H "Content-Type:application/json" --user secret_key: https://api.affinipay.com/v1/charges -d '
  {
      "amount": "39088",
      "account_id": "7eyWpvRpEeKcOfUBJK8FBw",
      "method": {
          "type": "bank",
          "routing_number": "000000013",
          "account_number": "1100000002",
          "account_type": "CHECKING",
          "name": "Customer Inc",
          "account_holder_type": "business"
      }
  }'
Example response
{
      "id": "GflPgzrBQsGu333bcBDDeA",
      "type": "CHARGE",
      "account_id": "7eyWpvRpEeKcOfUBJK8FBw",
      "status": "AUTHORIZED",
      "amount": 39088,
      "currency": "USD",
      "auto_capture": "true",
      "amount_refunded": 0,
      "authorization_code": "ZGBAIF",
      "method": {
          "type": "bank",
          "routing_number": "******013",
          "account_number": "******0002",
          "account_type": "CHECKING",
          "fingerprint": "0R21SqvPDfkxagx8hkAE",
          "bank_name": "FIRST BANK OF TESTING",
          "name": "Customer Inc",
          "account_holder_type": "business"
      }
  }
  
Creating a Charge debiting a customer's individual bank account
curl -X POST -H "Content-Type:application/json" --user secret_key: https://api.affinipay.com/v1/charges -d '
  {
      "amount": "46531",
      "account_id": "7eyWpvRpEeKcOfUBJK8FBw",
      "method": {
          "type": "bank",
          "routing_number": "000000013",
          "account_number": "1100000005",
          "account_type": "CHECKING",
          "given_name": "Amy",
          "surname": "Customer"
      }
  }'
Example response
{
      "id": "iE0PgzrBQsGu333bcBDHH7",
      "type": "CHARGE",
      "account_id": "7eyWpvRpEeKcOfUBJK8FBw",
      "status": "AUTHORIZED",
      "amount": 46531,
      "currency": "USD",
      "auto_capture": "true",
      "amount_refunded": 0,
      "authorization_code": "IHGUEN",
      "method": {
          "type": "bank",
          "routing_number": "******013",
          "account_number": "******0005",
          "account_type": "CHECKING",
          "fingerprint": "8341SqvPDfkxagx8hkHLH",
          "bank_name": "FIRST BANK OF TESTING",
          "given_name": "Amy",
          "surname": "Customer"
      }
  }
  

Charge with Surcharge

Merchants can provide an optional surcharge_amount element to a charge request to create a charge with surcharge.

To determine which transactions are surchargable, use hosted fields 1.4 or later and enable surcharge. See Creating payment forms using hosted fields.

The surcharge rate is set at the merchant level and can be a percentage or a flat rate. To include the amount plus surcharge on a charge, retrieve the total_amount and include it as the amount in the charge request. To include the surcharge amount on the receipt, include the surcharge_amount in the charge request.

Create a charge with surcharge
curl -X POST -H "Content-Type:application/json" --user <secret_key>: https://api.affinipay.com/v1/charges -d '
  {
      "method": "veaDMtNmQ8SzfwpcKtUTWA",
      "account_id": "wKgFeDz5HF-BPPl08dcADQ",
      "amount": "517500",
      "surcharge_amount": 17500;
      }
  }'
Example response
{
    "id": "Avwol61UQL6L7u9KFFNQeA",
    "created": "2022-09-30T17:09:12.460Z",
    "modified": "2022-09-30T17:09:12.497Z",
    "client_id": "43d3aea07dfef86f74a2466ddb87dcdd6ea3fc63b9961e5867200d441928f8",
    "account_id": "wKgFeDz5HF-BPPl08dcADQ",
    "status": "AUTHORIZED",
    "auto_capture": true,
    "amount": 517500,
    "currency": "USD",
    "authorization_code": "FECDKS",
    "surcharge_amount": 17500,
    "amount_refunded": 0,
    "type": "CHARGE",
    "method": {
        "name": "Ellen Grace",
        "address1": "111 New Street",
        "postal_code": "78756",
        "email": "egrace@example.com",
        "type": "card",
        "number": "************4242",
        "fingerprint": "5rxmQGOSB7jqlPd-vbux",
        "card_type": "VISA",
        "exp_month": 10,
        "exp_year": 2023
    },
    "cvv_result": "MATCHED",
    "avs_result": "ADDRESS_AND_POSTAL_CODE"
}

Charge with Recurrence

Merchants can provide an optional recur element to a charge request to create a recurring_charge. This is often useful when you want to start a new scheduled payment starting immediately, but want to ensure the first payment is successful first, or need to prorate an initial payment. When a recur element is provided, the Gateway validates the schedule information and then performs the charge.

If the authorization is declined, the failure reason is returned and no recurring charge is created. If, on the other hand, the charge is successfully authorized, a new recurring charge is created for which the initial recurring_charge_occurrence is marked PAID by the charge. The Gateway returns the new charge in the response JSON with a recurring_charge_id attribute containing the ID of the new recurring charge and a recurring_charge_occurrence_id attribute containing the ID of the paid occurrence.

Note: Only auto-capture charges can provide a recur structure. To use this feature, make sure to set auto_capture to true on the charge parameters.

The recur element is a JSON hash consisting of the following properties:

ParameterTypeDescription
descriptionStringDescription to be applied to the recurring charge (optional)
amountIntegerThe recurring amount to charge, in terms of the Charge's currency's smallest unit. For USD, this is the amount in cents. This property should only be set if the scheduled amount to collect differs from the initial payment amount specified on the charge. If not specified, the recurring charge amount will match the charge amount.
interval_unitStringThe interval unit of the schedule. Enumeration of:
  • DAY. Scheduled payments are performed every n days, based on the interval_delay
  • WEEK. Scheduled payments are performed every n weeks, based on the interval_delay
  • MONTH. Scheduled payments are performed every n months, based on the interval_delay
interval_delayNumberThe frequency with which the schedule is executed, in terms of the interval_unit. For example, if the interval unit is DAY, an interval delay of 1 means the schedule is executed every day; an interval delay of 2 means execution every other day; and an interval delay of 30 would mean the schedule is executed every 30 days.
endDateThe end date for the schedule such that the last occurrence is executed on or before this date (optional).
daysArray of StringSchedules for specific days of the week or month are created by defining the days property. This property can only be used with an interval_unit of WEEK or MONTH and an interval_delay of 1.

For weekly schedules, the values of this property are the ISO numeric days of the week: "1" for Monday, "2" for Tuesday, through "6" for Saturday and "7" for Sunday. For example, a schedule to be executed Mondays and Fridays would specify an array containing the values "1" and "5".

For monthly schedules, the values of this property are the days of the month, starting from "1", on which the schedule is executed. The keyword LAST can be used to indicate the last day of the month. For example, a schedule to be executed on the 15th and last days of each month would specify an array containing the values "15" and "LAST".

max_occurrencesNumberThe maximum number of scheduled payments that will be attempted before the recurring charge is automatically marked completed. Note that maximum occurrences tracks scheduled payments, and not actual transactions created to collect on those scheduled payments. For example, a Charge associated with an occurrence may initially fail if the credit card associated with the recurring charge is declined or expired; however, after the payment details are updated, a subsequent Charge associated with the same occurrence may succeed. In this scenario, however, only a single occurrence is counted towards the max_occurrences limit.
max_amountNumberThe maximum amount the recurring charge will attempt to collect before the recurring charge is automatically marked completed. This value must be greater than or equal to amount. The final occurrence of a recurring charge will be the lesser of amount and the remainder of max_amount less total_amount. For example, a recurring charge with a scheduled amount of $100 and a maximum amount of $150 will result in an initial occurrence for $100 followed by a final occurrence of $50. Note that max_amount, just like max_occurrences, tracks scheduled payments, and not actual transactions created to collect on those scheduled payments.
Create a monthly recurring charge from a saved Card for $20.00 starting today
curl -X POST -H "Content-Type:application/json" --user <secret_key>: https://api.affinipay.com/v1/charges -d '
  {
      "amount": "2000",
      "method": "K_5tUK78SKKpNKu9F8fvIw",
      "account_id": "diON4KOPnesamprmrxA8Iuo",
      "reference": "Donation Plan #1234",
      "recur": {
          "description": "Monthly donation from Sample Customer",
          "interval_unit": "MONTH",
          "interval_delay": 1
      }
  }'
Example response
{
      "id": "PUZt8B_fTCWCO25SJfMY6A",
      "account_id": "diON4KOPnesamprmrxA8Iuo",
      "status": "AUTHORIZED",
      "auto_capture": true,
      "amount": 2000,
      "currency": "USD",
      "reference": "Donation Plan #1234",
      "authorization_code": "FLCF19",
      "method": {
          "number": "************4242",
          "fingerprint": "GunPelYVthifNV63LEw1",
          "card_type": "VISA",
          "exp_month": 10,
          "exp_year": 2025,
          "name": "Sample Customer",
          "address1": "123 Main St",
          "city": "Austin",
          "state": "TX",
          "postal_code": "78730",
          "type": "card"
      },
      "amount_refunded": 0,
      "cvv_result": "MATCHED",
      "avs_result": "ADDRESS_AND_POSTAL_CODE",
      "recurring_charge_id": "Ou5d_4XxTBi1hWKKF1iY5g",
      "recurring_charge_occurrence_id": "tO6EA6oPRtSa7mX3vaupuQ",
      "type": "CHARGE"
}
Create a bi-weekly recurring charge from a saved Card for $75.00 with an initial payment of $250 starting today
curl -X POST -H "Content-Type:application/json" --user <secret_key>: https://api.affinipay.com/v1/charges -d '
  {
      "amount": "25000",
      "method": "K_5tUK78SKKpNKu9F8fvIw",
      "account_id": "diON4KOPnesamprmrxA8Iuo",
      "recur": {
          "amount": 7500,
          "interval_unit": "WEEK",
          "interval_delay": 2
      }
  }'
Example response
{
      "id": "XvUHFfZlQpur0QFABEF0Pw",
      "account_id": "diON4KOPnesamprmrxA8Iuo",
      "status": "AUTHORIZED",
      "auto_capture": true,
      "amount": 25000,
      "currency": "USD",
      "authorization_code": "EMAOYY",
      "method": {
          "number": "************4242",
          "fingerprint": "GunPelYVthifNV63LEw1",
          "card_type": "VISA",
          "exp_month": 10,
          "exp_year": 2025,
          "name": "Sample Customer",
          "address1": "123 Main St",
          "city": "Austin",
          "state": "TX",
          "postal_code": "78730",
          "type": "card"
      },
      "amount_refunded": 0,
      "cvv_result": "MATCHED",
      "avs_result": "ADDRESS_AND_POSTAL_CODE",
      "recurring_charge_id": "V9Sg2WcJSca-gZWYrYQ13w",
      "recurring_charge_occurrence_id": "mNrrlHgNRjS0T8dc-uL1dQ",
      "type": "CHARGE"
}

Schedule a Charge

POST /v1/charges/{chargeId}/schedule

Merchants can use this endpoint to create a recurring charge that uses the same details as a previously processed payment (e.g., payment method, customer information).

Whereas Charge with Recurrence allows you to define a recurring charge plus an initial payment and Create Recurring Charge allows you to define a recurring charge for future payments only, Schedule a Charge allows you to reuse an existing transaction to define a new recurring charge schedule.

Tip: Search for previously processed payments using the /transactions endpoint.

The following parameters are required:

ParameterTypeDescription
amountIntegerThe recurring amount to charge, in terms of the currency's smallest unit. For USD, this is the amount in cents.
scheduleScheduleThe schedule indicating when payments are due. The following properties are required:
  • start
  • interval_unit
  • interval_delay

All other schedule properties are optional.

Upon creation or update of a recurring charge, the Gateway calculates the next payment using the given schedule along with the configured start date and current date. For start dates occurring before the current date, the next payment is defined as the next eligible date (based on the schedule) on or after the current date.

Create a monthly recurring charge from an existing payment for $100 starting on 2017-04-01
curl -X POST -H "Content-Type:application/json" --user <secret_key>: https://api.affinipay.com/v1/charges/2wB4BNIRQMyaSrMBbYrW-Q//schedule -d '
  {
      "amount": "10000",
      "schedule": {
        "start": "2017-04-01",
        "interval_unit": "MONTH",
        "interval_delay": "1"
      }
  }'
Example response
{
  "id": "r0LMZjzLTBSMyvYFWT55-A",
  "created": "2017-03-28T13:45:24.824Z",
  "modified": "2017-03-28T13:45:24.824Z",
  "status": "ACTIVE",
  "account_id": "diON4KOPnesamprmrx-Iuo",
  "schedule": {
    "interval_unit": "MONTH",
    "interval_delay": 1,
    "start": "2017-04-01"
  },
  "amount": 10000,
  "currency": "USD",
  "total_occurrences": 0,
  "total_amount": 0,
  "next_payment": "2017-04-01",
  "occurrences": [
    {
      "id": "YVvhsTBBQNa9kM3j18CiZg",
      "created": "2017-03-28T13:45:24.824Z",
      "modified": "2017-03-28T13:45:24.824Z",
      "recurring_charge_id": "r0LMZjzLTBSMyvYFWT55-A",
      "amount": 10000,
      "status": "PENDING",
      "due_date": "2017-04-01",
      "attempts": 0
    }
  ],
  "method": {
    "name": "Dave Bowman",
    "address1": "2001 Space Odyssey Ln",
    "postal_code": "78750",
    "email": "devsupport@affinipay.com",
    "type": "card",
    "number": "************4242",
    "fingerprint": "GunPelYVthifNV63LEw1",
    "card_type": "VISA",
    "exp_month": 10,
    "exp_year": 2025
  }
}

Get Surcharge

GET /bank-accounts/{bank_account_id}/surcharge

Retrieves the surcharge rate and fee for the specified bank account, using a public key and basic authentication. This includes rates and fees for card, bank, and loan types, when available. If a bank account has more than one of the same type, the first one is returned. If the merchant does not have surcharge enabled, a null set is returned.

If an amount is specified, the response includes:

  • amount. The subtotal from which the surcharge was calculated (in cents).
  • surcharge_amount. The amount to be surcharged (in cents). This amount is equal to the surcharge fee or to the amount multiplied by the surcharge rate.
  • total_amount. The total amount that should be used when running the final charge (in cents).
Before you begin, retrieve the bank account ID.

The following URI parameter is required:

ParameterDescription
bank_account_idThe system-generated ID of a bank account. (required)

The following query parameter is optional:

ParameterTypeDescription
amountNumberThe subtotal from which the surcharge will be calculated (in cents).
Retrieving surcharge information for an account
curl -X GET --user public_key: https://api.affinipay.com/bank-accounts/bank_eZX3KANx7JyXDCrMQkdLj/surcharge
Example response
[
    {
        "type": "card",
        "surcharge_rate": 350,
        "surcharge_fee": 0
    },
    {
        "type": "bank",
        "surcharge_rate": 0,
        "surcharge_fee": 1001
    }
]
  
Retrieving surcharge information for an amount
curl -X GET --user public_key: https://api.affinipay.com/bank-accounts/bank_eZX3KANx7JyXDCrMQkdLj/surcharge?amount=500000
Example response
[
    {
        "type": "card",
        "surcharge_rate": 350,
        "surcharge_fee": 0,
        "amount": 500000,
        "surcharge_amount": 17500,
        "total_amount": 517500
    },
    {
        "type": "bank",
        "surcharge_rate": 0,
        "surcharge_fee": 1001,
        "amount": 500000,
        "surcharge_amount": 1001,
        "total_amount": 501001
    }
]
  

Capture

POST /v1/charges/{chargeId}/capture

Merchants use the capture API to control the settlement of authorization-only Charges (those Charges created with auto_capture: false), which initiates the transfer of funds from the credit card holder's bank to the Merchant's account. This feature is only available for credit card transactions, and must be enabled by the Tenant on a per-account basis.

Charges created with auto_capture: true, or without specifying any value for this property, are captured automatically by the Gateway daily, and require no Merchant interaction to initiate settlement. When a Charge is created with auto_capture: false, however, a hold is placed on the customer's funds for the amount specified, but the transaction will not be settled unless the Merchant issues a capture request for the funds.

A capture is performed by issuing a POST to /v1/charges/{chargeId}/capture. The updated transaction is returned in the JSON response. The request content consists of a JSON hash including the following properties:

ParameterTypeDescription
amountIntegerThe amount to capture, in terms of the Charge's currency's smallest unit. For USD, this is the amount in cents. The captured amount must be equal to the originally authorized amount.
referenceStringA reference to be applied to the transaction for the capture operation (optional, maximum length is 128 characters)
capture_timeStringWhen the capture should be performed. If no value is specified, the default behavior is IMMEDIATE (funds are captured immediately within the current request). Enumeration of:
  • IMMEDIATE. The funds are captured immediately within the current request
  • NEXT_AUTO_CAPTURE. The auto_capture property of the Charge is changed to true and the Charge is captured during the next scheduled automatic capture for the underlying Merchant Account
Example request
curl -X POST -H "Content-Type:application/json" --user secret_key: https://api.affinipay.com/v1/charges/wKgFnjz8GamBPP0HTv0ABQ/capture -d '
  {
      "amount":"95"
  }'
Example response
{
      "id": "wKgFnjz8GamBPP0HTv0ABQ",
      "type": "CHARGE",
      "account_id": "wKgFeDz5HF-BPPl08dcADQ",
      "status": "COMPLETED",
      "completion_timestamp": "2019-11-25T05:14:27.000-06:00",
      "amount": 95,
      "currency": "USD",
      "auto_capture": false,
      "amount_refunded": 0,
      "authorization_code": "VXQEJU",
      "method": {
          "type": "card",
          "number": "************4242",
          "fingerprint": "CmsP3lYV4akuOz12pFa8",
          "card_type": "VISA",
          "exp_month": 10,
          "exp_year": 2025
      }
  }
  

Authorization Holds

GET /v1/charges/holds

If you create authorization-only charges (charges with auto_capture: false), you'll need to issue separate requests to settle those transactions using the Capture API. Use this endpoint to retrieve a list of all unsettled authorization-only charges associated with an authenticated merchant. Authorization-only charges may be returned for a specific merchant account or from all the merchant's accounts.

The API supports pagination over the result set by allowing the client to specify the number of results per logical "page", the page to view, and filtering. The following optional URL parameters are supported:

ParameterDescription
pageThe page number to view, starting from 1 (optional, defaults to 1)
page_sizeThe number of results to return per logical page (optional, defaults to 20, max is 100)
account_idIf specified, only transactions processed through the specified account are returned; if omitted, transactions are returned associated with all of the Merchant's accounts.
Example request
curl -X GET --user secret_key: 'https://api.affinipay.com/v1/charges/holds?page=1&page_size=5'
Example response
{
  "page" : 1,
  "page_size" : 5,
  "total_entries" : 1,
  "results" : [ {
    "id" : "gOUE9tJZQ9C9u-0ax3uEcw",
    "created" : "2017-01-12T20:25:36.032Z",
    "modified" : "2017-01-12T20:25:36.091Z",
    "account_id" : "Z7kmjXdbQdS9Q7dXLZ-mKg",
    "status" : "AUTHORIZED",
    "auto_capture" : false,
    "amount" : 50000,
    "currency" : "USD",
    "authorization_code" : "SFGGMY",
    "amount_refunded" : 0,
    "type" : "CHARGE",
    "method" : {
      "name" : "Dave Bowman",
      "address1" : "123 Main St",
      "city" : "Austin",
      "state" : "TX",
      "postal_code" : "78730",
      "type" : "card",
      "number" : "************4242",
      "fingerprint" : "GunPelYVthifNV63LEw1",
      "card_type" : "VISA",
      "exp_month" : 10,
      "exp_year" : 2025
    },
    "cvv_result" : "MATCHED",
    "avs_result" : "ADDRESS_AND_POSTAL_CODE"
  } ]
}
  

Refunds

POST /v1/charges/{chargeId}/refund

A refund returns funds to a customer's account for a specified Charge, up to six months after the Charge. Multiple refunds may be performed up to the total amount authorized. Refunds can be applied to any auto-capture Charges for which the status is either AUTHORIZED or COMPLETED. Non-auto-capture Charges must be COMPLETED by a capture before refunds may be applied.

Refunds are always captured automatically by the Gateway. Refunds are queued up until the daily capture occurs, at which point the refunds are settled following any pending authorized Charges. The new Refund entity is returned in the response content.

By default, funds are returned to the payment method specified in the Charge (either a Card or Bank). If enabled by the Tenant, Refunds can be applied to a different credit card or bank account; however, the type of payment method cannot be changed. For example, a Charge to a credit card cannot be refunded to a bank account.

Refunds of Charges using a Bank as the payment method are queued until the status of the parent Charge is COMPLETED. This ensures that funds are properly deposited before the refund is performed. In this case, the status of the returned Refund is PENDING. The Gateway automatically performs the refund once settlement details for the parent Charge are received. In the event of a settlement failure, the status of the Refund is changed to FAILED and the failure code is updated. Note that a refund applied to a COMPLETED Bank Charge is performed immediately.

Applying a refund to a credit card charge
curl -X POST -H "Content-Type:application/json" --user secret_key: https://api.affinipay.com/v1/charges/wKgFnjz8GamBPPzKzIsAAA/refund -d '
  {
      "amount":"20"
  }'
Example response
{
      "id": "wKgFnjz8GamBPPzVF2kAAg",
      "type": "REFUND",
      "account_id": "wKgFeDz5HF-BPPl08dcADQ",
      "status": "AUTHORIZED",
      "amount": 20,
      "currency": "USD",
      "auto_capture": true,
      "charge_id": "wKgFnjz8GamBPPzKzIsAAA",
      "method": {
          "type": "card",
          "number": "************4242",
          "fingerprint": "CmsP3lYV4akuOz12pFa8",
          "card_type": "VISA",
          "exp_month": 10,
          "exp_year": 2025,
          "name": "Sample Customer"
      }
  }
  
Applying a refund to a settled bank charge
curl -X POST -H "Content-Type:application/json" --user secret_key: https://api.affinipay.com/v1/charges/GflPgzrBQsGu333bcBDDeA/refund -d '
  {
      "amount":"135"
  }'
Example response
{
      "id": "rXNUi7WXSkeyEvIuMPOaOw",
      "type": "REFUND",
      "account_id": "7eyWpvRpEeKcOfUBJK8FBw",
      "status": "AUTHORIZED",
      "amount": 135,
      "currency": "USD",
      "auto_capture": true,
      "charge_id": "GflPgzrBQsGu333bcBDDeA",
      "method": {
          "type": "bank",
          "routing_number": "******013",
          "account_number": "******0002",
          "account_type": "CHECKING",
          "fingerprint": "0R21SqvPDfkxagx8hkAE",
          "bank_name": "FIRST BANK OF TESTING",
          "name": "Customer Inc",
          "account_holder_type": "business"
      }
  }
  
Applying a refund to an authorized (unsettled) bank charge
curl -X POST -H "Content-Type:application/json" --user secret_key: https://api.affinipay.com/v1/charges/TUd8PkY3TwmsXcYeqoWsEA/refund -d '
  {
      "amount":"350"
  }'
Example response
{
      "id": "BO2ykwKDSRSzlvP7NTc9hw",
      "type": "REFUND",
      "account_id": "7eyWpvRpEeKcOfUBJK8FBw",
      "status": "PENDING",
      "amount": 350,
      "currency": "USD",
      "auto_capture": true,
      "charge_id": "TUd8PkY3TwmsXcYeqoWsEA",
      "method": {
          "type": "bank",
          "routing_number": "******013",
          "account_number": "******0002",
          "account_type": "CHECKING",
          "fingerprint": "0R21SqvPDfkxagx8hkAE",
          "bank_name": "FIRST BANK OF TESTING",
          "name": "Customer Inc",
          "account_holder_type": "business"
      }
  }
  

Voids

POST /v1/transactions/{transactionId}/void

Until an authorized transaction has been captured or settled, it may be voided, preventing any capture of funds from occurring and releasing any hold, by POSTing a request to /v1/transactions/{transactionId}/void. The updated transaction is returned in the response, its status changed to VOIDED. Charges, Refunds, and Credits may all be voided. However, once a Charge has been Refunded, it may no longer be voided unless all the Refunds are voided.

Note: A credit card charge is auto-voided when (1) it has remained in an authorized state for more than 7 days or (2) its CVV or AVS result is rejected by the processing account policy. By default, the partner policy for CVV is OPTIONAL and the partner policy for AVS is SUBMIT_IGNORE_RESULT. More strict policies may increase the chances of an auto-void.

The request may optionally include a JSON hash containing the following properties:

ParameterTypeDescription
referenceStringA reference to be applied to the transaction for the void operation (optional, maximum length is 128 characters)
Voiding a transaction
curl -X POST -H "Content-Type:application/json" --user secret_key: https://api.affinipay.com/v1/transactions/wKgFnjz8GamBPP0ASxIABA/void
Example response
{
      "id": "wKgFnjz8GamBPP0ASxIABA",
      "type": "CHARGE",
      "account_id": "wKgFeDz5HF-BPPl08dcADQ",
      "status": "VOIDED",
      "amount": 100,
      "currency": "USD",
      "auto_capture": false,
      "amount_refunded": 0,
      "authorization_code": "DSFCCO",
      "method": {
          "type": "card",
          "number": "************4242",
          "fingerprint": "CmsP3lYV4akuOz12pFa8",
          "card_type": "VISA",
          "exp_month": 10,
          "exp_year": 2025,
          "name": "Sample Customer",
          "address1": "123 Main St",
          "city": "Austin",
          "state": "TX",
          "postal_code": "78730"
      }
  }
  
Voiding a transaction with a reference
curl -X POST -H "Content-Type:application/json" --user secret_key: https://api.affinipay.com/v1/transactions/wKgFnjz8GamBPP0ASxIABA/void -d '
  {
      "reference": "An explanation for why the charge was voided"
  }'
Example response
{
      "id": "wKgFnjz8GamBPP0ASxIABA",
      "type": "CHARGE",
      "account_id": "wKgFeDz5HF-BPPl08dcADQ",
      "status": "VOIDED",
      "amount": 100,
      "currency": "USD",
      "auto_capture": false,
      "amount_refunded": 0,
      "authorization_code": "DSFCCO",
      "void_reference": "An explanation for why the charge was voided",
      "method": {
          "type": "card",
          "number": "************4242",
          "fingerprint": "CmsP3lYV4akuOz12pFa8",
          "card_type": "VISA",
          "exp_month": 10,
          "exp_year": 2025,
          "name": "Sample Customer",
          "address1": "123 Main St",
          "city": "Austin",
          "state": "TX",
          "postal_code": "78730"
      }
  }
  

Credits

POST /v1/credits

A credit allows you to return funds to a customer credit card or bank account independent of any existing Charges. Credits can be used to refund customers using payment methods that do not match the originating payment type, or to accommodate scenarios in which the original payment method is no longer available. The Credit API is disabled by default, and must be enabled by AffiniPay on a per-account basis.

A Credit is created by sending an amount and payment method in a JSON POST to /v1/credits. If no account ID is specified in the request, the Gateway automatically selects the primary merchant or eCheck account, depending on the type of payment method specified; for example, providing a bank method results in the primary eCheck account being selected. If no matching account is found, or if an account ID is provided but does not match the payment method, the credit is rejected.

The Gateway authorizes the funds transfer and returns the JSON Credit in the response. Credits are captured automatically by the Gateway on a daily basis.

Credit funds to a credit card
curl -X POST -H "Content-Type:application/json" --user secret_key: https://api.affinipay.com/v1/credits -d '
  {
      "amount": "1255",
      "method": {
          "type": "card",
          "number": "4242424242424242",
          "exp_month": 10,
          "exp_year": 2025,
          "cvv": "123",
          "name": "Sample Customer",
          "address1": "123 Main St",
          "city": "Austin",
          "state": "TX",
          "postal_code": "78730"
      }
  }'
Example response
{
      "id": "mj6BKuWjTqeXRGL7zZZapA",
      "type": "CREDIT",
      "account_id": "wKgFeDz5HF-BPPl08dcADQ",
      "status": "AUTHORIZED",
      "amount": 1255,
      "currency": "USD",
      "method": {
          "type": "card",
          "number": "************4242",
          "fingerprint": "CmsP3lYV4akuOz12pFa8",
          "card_type": "VISA",
          "exp_month": 10,
          "exp_year": 2025,
          "name": "Sample Customer",
          "address1": "123 Main St",
          "city": "Austin",
          "state": "TX",
          "postal_code": "78730"
      }
  }
  
Credit funds to a bank account
curl -X POST -H "Content-Type:application/json" --user secret_key: https://api.affinipay.com/v1/credits -d '
  {
      "amount": "18000",
      "method": {
          "type": "bank",
          "routing_number": "000000013",
          "account_number": "1100000003",
          "account_type": "SAVINGS"
          "name": "Customer Inc",
          "account_holder_type": "business"
      }
  }'
Example response
{
      "id": "OHqxGhSTT3KckThAEhX57A",
      "type": "CREDIT",
      "account_id": "7eyWpvRpEeKcOfUBJK8FBw",
      "status": "AUTHORIZED",
      "amount": 18000,
      "currency": "USD",
      "method": {
          "type": "bank",
          "routing_number" : "******013",
          "account_number" : "******0003",
          "account_type" : "SAVINGS",
          "fingerprint" : "4LPFVT7k2aQB3J70ZBGH",
          "bank_name": "FIRST BANK OF TESTING",
          "name": "Customer Inc",
          "account_holder_type": "business"
      }
  }
  
Credit funds to a one-time or saved payment method
curl -X POST -H "Content-Type:application/json" --user secret_key: https://api.affinipay.com/v1/credits -d '
  {
      "amount": "18000",
      "method": "vU42KZWhTd2iiGLhjfJR6A"
  }'
Example response
{
      "id": "dkWEi9yYQrCmBhNZYOALRA",
      "type": "CREDIT",
      "account_id": "7eyWpvRpEeKcOfUBJK8FBw",
      "status": "AUTHORIZED",
      "amount": 2398,
      "currency": "USD",
      "method": {
          "type": "bank",
          "routing_number" : "******013",
          "account_number" : "******0003",
          "account_type" : "SAVINGS",
          "fingerprint" : "4LPFVT7k2aQB3J70ZBGH",
          "bank_name": "FIRST BANK OF TESTING",
          "name": "Customer Inc",
          "account_holder_type": "business"
      }
  }
  

Submit Signature

POST /v1/transactions/{transactionId}/sign

A Merchant may submit a cardholder's signature in association with a transactionID.

The request takes a signature that can be captured directly using the AffiniPay mobile app.

Submitting a signature for a transaction
curl -X POST --user secret_key: https://api.affinipay.com/v1/transactions/wKgFnjz8GamBPP0ASxIABA/sign
  {
	"mime_type":"chargeio/jsignature",
	"data":"[{\"x\":[179,179,179,179,180,188,195,206,218,228,245,252,261,267,270,270,269,262,254,246,237,230,225,221,219,219,222,229,239,251,263,274,282,286,288,289,286],\"y\":[77,84,89,97,104,113,120,127,132,133,133,133,128,121,114,106,99,93,87,85,85,85,87,93,99,109,120,129,138,144,146,147,145,141,134,130,127]}]"
  }
Example response
{
    "signature_id": "aogEK5489vNb21lE89gh3",
    "signature": {
        "mime_type":"chargeio/jsignature",
        "data":"[{\"x\":[179,179,179,179,180,188,195,206,218,228,245,252,261,267,270,270,269,262,254,246,237,230,225,221,219,219,222,229,239,251,263,274,282,286,288,289,286],\"y\":[77,84,89,97,104,113,120,127,132,133,133,133,128,121,114,106,99,93,87,85,85,85,87,93,99,109,120,129,138,144,146,147,145,141,134,130,127]}]"
    }
}
  

Get Signature

GET /v1/signatures/{signatureId}

A Merchant can retrieve a signature using its signatureID.

Retrieving a signature
curl -X GET --user secret_key: https://api.affinipay.com/v1/transactions/aogEK5489vNb21lE89gh3
Example response
{
    "id": "aogEK5489vNb21lE89gh3",
    "created": "2018-01-28T13:45:24.824Z",
    "signature": {
        "mime_type":"chargeio/jsignature",
        "data":"[{\"x\":[179,179,179,179,180,188,195,206,218,228,245,252,261,267,270,270,269,262,254,246,237,230,225,221,219,219,222,229,239,251,263,274,282,286,288,289,286],\"y\":[77,84,89,97,104,113,120,127,132,133,133,133,128,121,114,106,99,93,87,85,85,85,87,93,99,109,120,129,138,144,146,147,145,141,134,130,127]}]"
    }
}
  

Get Transaction by ID

GET /v1/transactions/{transactionId}

A Merchant may retrieve any transaction created through one of its own Accounts by performing a GET to /v1/transactions/{transactionId}, where transactionId is the ID of the transaction of interest. The Gateway returns the JSON for the transaction. The JSON type attribute indicates the kind of transaction (charge or refund). Charges returned via this API include any subsequent Refunds.

Retrieving a credit card Charge with Refunds
curl -X GET --user secret_key: https://api.affinipay.com/v1/transactions/wKgBZTynEtOBPKjE2VAACA
Example response
{
      "id": "wKgBZTynEtOBPKjE2VAACA",
      "type": "CHARGE",
      "account_id": "wKgFeDz5HF-BPPl08dcADQ",
      "status": "AUTHORIZED",
      "amount": 95,
      "currency": "USD",
      "auto_capture": true,
      "amount_refunded": 20,
      "authorization_code": "YXXLPC",
      "method": {
          "type": "card",
          "number": "************4242",
          "fingerprint": "CmsP3lYV4akuOz12pFa8",
          "card_type": "VISA",
          "exp_month": 10,
          "exp_year": 2025,
          "name": "Sample Customer",
          "address1": "123 Main St",
          "postal_code": "78730"
      },
      "refunds": [
          {
              "id": "wKgFnjz8GamBPP0S54gACA",
              "type": "REFUND",
              "account_id": "wKgFeDz5HF-BPPl08dcADQ",
              "status": "AUTHORIZED",
              "amount": 20,
              "currency": "USD",
              "method": {
                  "type": "card",
                  "number": "************4242",
                  "fingerprint": "CmsP3lYV4akuOz12pFa8",
                  "card_type": "VISA",
                  "exp_month": 10,
                  "exp_year": 2025,
                  "name": "Sample Customer",
                  "address1": "123 Main St",
                  "postal_code": "78730"
              }
          }
      ]
  }
  
Retrieving a credit to a bank account
curl -X GET --user secret_key: https://api.affinipay.com/v1/transactions/OHqxGhSTT3KckThAEhX57A
Example response
{
      "id": "OHqxGhSTT3KckThAEhX57A",
      "type": "CREDIT",
      "account_id": "7eyWpvRpEeKcOfUBJK8FBw",
      "status": "COMPLETED",
      "completion_timestamp": "2019-11-25T05:14:27.000-06:00",
      "amount": 18000,
      "currency": "USD",
      "method": {
          "type": "bank",
          "routing_number": "******013",
          "account_number": "******0003",
          "account_type": "SAVINGS",
          "fingerprint": "4LPFVT7k2aQB3J70ZBGH",
          "bank_name": "FIRST BANK OF TESTING",
          "name": "Customer Inc",
          "account_holder_type": "business"
      }
  }
  

Get Transaction by Source ID

GET /v1/transactions/source-id?id={source_id}

A Merchant may retrieve any transaction created through one of its own Accounts by performing a GET to /v1/transactions/source-id?id={source_id}, where source_id is the source ID of the transaction of interest. The Gateway returns the JSON for the transaction, which does not include the source_id. The JSON type attribute indicates the kind of transaction (charge or refund). Charges returned via this API include any subsequent Refunds.

Retrieving a charge using its source ID
curl -X GET --user secret_key: https://api.affinipay.com/v1/transactions/source-id?id=test:123456789
Example response
{
      "id": "wKgBZTynEtOBPKjE2VAACA",
      "type": "CHARGE",
      "account_id": "wKgFeDz5HF-BPPl08dcADQ",
      "status": "AUTHORIZED",
      "amount": 95,
      "currency": "USD",
      "auto_capture": true,
      "amount_refunded": 20,
      "authorization_code": "YXXLPC",
      "method": {
          "type": "card",
          "number": "************4242",
          "fingerprint": "CmsP3lYV4akuOz12pFa8",
          "card_type": "VISA",
          "exp_month": 10,
          "exp_year": 2025,
          "name": "Sample Customer",
          "address1": "123 Main St",
          "postal_code": "78730"
      },
      "refunds": [
          {
              "id": "wKgFnjz8GamBPP0S54gACA",
              "type": "REFUND",
              "account_id": "wKgFeDz5HF-BPPl08dcADQ",
              "status": "AUTHORIZED",
              "amount": 20,
              "currency": "USD",
              "method": {
                  "type": "card",
                  "number": "************4242",
                  "fingerprint": "CmsP3lYV4akuOz12pFa8",
                  "card_type": "VISA",
                  "exp_month": 10,
                  "exp_year": 2025,
                  "name": "Sample Customer",
                  "address1": "123 Main St",
                  "postal_code": "78730"
              }
          }
      ]
  }
  

Search Transactions

GET /v1/transactions

The transactions associated with the authenticated merchant are returned via a GET request to /v1/transactions. Transactions may be returned for a specific account or from all the Merchant's accounts.

The API supports pagination over the result set by allowing the client to specify the number of results per logical "page" and the page to view. The following URL parameters are supported:

ParameterDescription
pageThe page number to view, starting from 1 (optional, defaults to 1)
page_sizeThe number of results to return per logical page (optional, defaults to 20, max is 100)
qA search query string to be matched against transactions. The given text is matched against all fields of the transactions. For matching on specific fields, use the qf parameter instead. (Optional)
qfA search term to be matched. The value is composed of a name of a property to match, followed by a ':' character, followed by the text to match. For example, transactions involving a customer whose last name starts with "Targ" would be found using the URL: /v1/transactions?qf=name:Targ. The parameter can be specified multiple times to create a more constrained search across multiple terms. For example, the previous search could be narrowed to those customers in the US state of Texas: /v1/transactions?qf=name:Targ&qf=state:TX.

Nested properties can be specified by separating the properties with a '.' character. For example, transactions using a bank payment method would be returned using the URL: /v1/transactions?qf=method.type:bank. (Optional)

start_dateOnly transactions created after the specified date/time are returned. The timestamp must be in the format yyyy-MM-dd'T'HH:mm:ss.SSS'Z'. All transactions are returned by default.
end_dateOnly transactions created before the specified date/time are returned. The timestamp must be in the format yyyy-MM-dd'T'HH:mm:ss.SSS'Z'. All transactions are returned by default.
account_idIf specified, only transactions processed through the specified account are returned; if omitted, transactions are returned associated with all of the Merchant's accounts.
order_byA comma-separated list of properties used to sort the results. By default, the results are sorted in ascending order by the property. Each property may optionally be preceded by a '-' or '+' character to specify descending or ascending sort order.
Retrieve the 5 most recent transactions:
curl -X GET --user secret_key: 'https://api.affinipay.com/v1/transactions?page=1&page_size=5&order_by=-created'
Example response
{
      "page": 1,
      "page_size": 5,
      "total_entries": 82,
      "results": [
          {
              "id": "wKgFnjz8GamBPP0ViHAACQ",
              "type": "REFUND",
              "created": "2019-11-24T14:36:27.000-06:00",
              "account_id": "wKgFeDz5HF-BPPl08dcADQ",
              "status": "COMPLETED",
              "completion_timestamp": "2019-11-24T05:14:27.000-06:00",
              "amount": 18,
              "currency": "USD",
              "charge_id" : "wKgFnjz8GamBPP0SBFoABw",
              "method": {
                  "type": "card",
                  "number": "************0057",
                  "fingerprint": "EEsXiql10dDbe1773r5d",
                  "card_type": "MASTERCARD",
                  "exp_month": 12,
                  "exp_year": 2025,
                  "name": "Sample Customer",
                  "address1": "123 Main St",
                  "postal_code": "78730"
              }
          }, {
              "id": "wKgFnjz8GamBPP0S54gACA",
              "type": "CHARGE",
              "created": "2019-11-21T08:06:19.000-06:00",
              "account_id": "7eyWpvRpEeKcOfUBJK8FBw",
              "status": "COMPLETED",
              "completion_timestamp": "2019-11-21T05:14:27.000-06:00",
              "amount": 2100,
              "currency": "USD",
              "method": {
                  "type": "bank",
                  "routing_number": "******013",
                  "account_number": "******0003",
                  "account_type": "SAVINGS",
                  "fingerprint": "4LPFVT7k2aQB3J70ZBGH",
                  "bank_name": "FIRST BANK OF TESTING",
                  "name": "Customer Inc",
                  "account_holder_type": "business"
              }
          }, {
              "id": "wKgFnjz8GamBPP0SBFoABw",
              "type": "CHARGE",
              "created": "2019-11-21T08:04:41.000-06:00",
              "account_id": "wKgFeDz5HF-BPPl08dcADQ",
              "status": "COMPLETED",
              "completion_timestamp": "2019-11-21T05:14:27.000-06:00",
              "amount": 95,
              "currency": "USD",
              "auto_capture": true,
              "amount_refunded": 18,
              "authorization_code": "LV1AFL",
              "method": {
                  "type": "card",
                  "number": "************4242",
                  "fingerprint": "CmsP3lYV4akuOz12pFa8",
                  "card_type": "VISA",
                  "exp_month": 10,
                  "exp_year": 2025,
                  "name": "Sample Customer",
                  "address1": "123 Main St",
                  "postal_code": "78730"
              }
          }, {
              "id": "wKgBZTynEtOBPKi_AjoABg",
              "type": "CHARGE",
              "created": "2019-11-25T05:14:27.000-06:00",
              ...
          }, {
              "id": "wKgBZTynEtOBPKhlyA0AAQ",
              "type": "CHARGE",
              "created": "2019-11-04T21:28:28.000-06:00",
              "account_id": "wKgeRDynFnyBPKdn4XsABA",
              "status": "COMPLETED",
              "completion_timestamp": "2019-11-04T05:14:27.000-06:00",
              "amount": 100,
              "currency": "USD",
              "auto_capture": true,
              "amount_refunded": 0,
              "authorization_code": "UKNTTH",
              "method": {
                  "type": "card",
                  "number": "************4242",
                  "fingerprint": "CmsP3lYV4akuOz12pFa8",
                  "card_type": "VISA",
                  "exp_month": 10,
                  "exp_year": 2025,
                  "name": "Some Customer"
              }
          }
      ]
  }
  
Retrieve the 5 most recent Charges
curl -X GET --user secret_key: https://api.affinipay.com/v1/transactions?page=1&page_size=5&order_by=-created&qf=type:CHARGE
Example response
{
      "page": 1,
      "page_size": 5,
      "total_entries": 82,
      "results": [
          {
              "id": "wKgFnjz8GamBPP0SBFoABw",
              "type": "CHARGE",
              "created": "2019-11-21T08:04:41.000-06:00",
              "account_id": "wKgFeDz5HF-BPPl08dcADQ",
              "status": "COMPLETED",
              "completion_timestamp": "2019-11-21T05:14:27.000-06:00",
              "amount": 95,
              "currency": "USD",
              "auto_capture": true,
              "amount_refunded": 18,
              "authorization_code": "LV1AFL",
              "method": {
                  "type": "card",
                  "number": "************4242",
                  "fingerprint": "CmsP3lYV4akuOz12pFa8",
                  "card_type": "VISA",
                  "exp_month": 10,
                  "exp_year": 2025,
                  "name": "Sample Customer",
                  "address1": "123 Main St",
                  "postal_code": "78730"
              }
          }, {
              "id": "wKgBZTynEtOBPKi_AjoABg",
              "type": "CHARGE",
              "created": "2019-11-17T23:05:55.000-06:00",
              ...
          }, {
              "id": "wKgBZTynEtOBPKhlyA0AAQ",
              "type": "CHARGE",
              "created": "2019-11-04T21:28:28.000-06:00",
              ...
          }, {
              "id": "EcE2jKH3QeOBhOvnvAugpQ",
              "type": "CHARGE",
              "created": "2019-11-03T17:43:19.000-06:00",
              ...
          }, {
              "id": "lyh3fKDSTi-S4EbAqNdKCg",
              "type": "CHARGE",
              "created": "2019-11-03T17:29:01.000-06:00",
              ...
          }
      ]
  }
  
Retrieve the 5 most recent credit card refunds
curl -X GET --user secret_key: https://api.affinipay.com/v1/transactions?page=1&page_size=5&order_by=-created&qf=type:REFUND&qf=method.type:card
Example response
{
      "page": 1,
      "page_size": 5,
      "total_entries": 82,
      "results": [
          {
              "id": "wKgFnjz8GamBPP0ViHAACQ",
              "type": "REFUND",
              "created": "2019-11-24T14:36:27.000-06:00",
              "account_id": "wKgFeDz5HF-BPPl08dcADQ",
              "status": "COMPLETED",
              "completion_timestamp": "2019-11-24T05:14:27.000-06:00",
              "amount": 18,
              "currency": "USD",
              "charge_id" : "wKgFnjz8GamBPP0SBFoABw",
              "method": {
                  "type": "card",
                  "number": "************0057",
                  "fingerprint": "EEsXiql10dDbe1773r5d",
                  "card_type": "MASTERCARD",
                  "exp_month": 12,
                  "exp_year": 2025,
                  "name": "Sample Customer",
                  "address1": "123 Main St",
                  "postal_code": "78730"
              }
          }, {
              "id": "-adgFlH-TUSV3M4_sVXvKQ",
              "type": "REFUND",
              "created": "2019-11-01T08:55:19.000-06:00",
              ...,
              "method": {
                  "type": "card",
                  ...
              }
          }, {
              "id": "y4CfMEZERXuTeXEqMkUd2w",
              "type": "REFUND",
              "created": "2019-11-01T07:36:08.000-06:00",
              ...,
              "method": {
                  "type": "card",
                  ...
              }
          }, {
              "id": "DOPApiYlEeOfvhLxg70sog",
              "type": "REFUND",
              "created": "2019-11-30T18:04:44.000-06:00",
              ...,
              "method": {
                  "type": "card",
                  ...
              }
          }, {
              "id": "lbBObpbATdCj1lfX9fM6Aw",
              "type": "REFUND",
              "created": "2019-11-30T12:11:26.000-06:00",
              ...,
              "method": {
                  "type": "card",
                  ...
              }
          }
      ]
  }
  

Recurring Charges

The Gateway's recurring charge support makes it easy to collect payments from your customers on an ongoing, scheduled basis — from simple donations to more complicated installment plans.

Start by creating a new recurring charge, which includes:

  • Defining how much to collect
  • Specifying a payment method to use
  • Configuring the payment schedule and optional limits

Tip: We highly recommend masking payment details you collect using tokenization. If you choose not to use tokens and plan on handling sensitive cardholder data yourself, you'll need to implement robust security policies and comply with more stringent PCI requirements.

The Gateway tracks each scheduled payment using an occurrence instance, which lets you know the status of the payment and what transaction(s) were created to collect that payment. Through the APIs, you can:

Create Recurring Charge

POST /v1/recurring/charges

A new recurring charge is created by POSTing a recurring_charge to /v1/recurring/charges. The Gateway schedules the first payment recurring_charge_occurrence and returns the new recurring charge in the response.

Note: A recurring charge cannot be scheduled to start on the same day it is created. Doing so will result in a first_occurrence_due_immediately error being returned.

Creating a monthly recurring charge from a saved credit card:
curl -X POST -H "Content-Type:application/json" --user <secret_key>: https://api.affinipay.com/v1/recurring/charges -d '
  {
      "description": "Monthly recurring charge",
      "account_id": "wKgFeDz5HF-BPPl08dcADQ",
      "amount": "1250",
      "method": "OtmNJP6YRpKrcJ0RdZxGcw",
      "schedule": {
          "start": "2016-01-01",
          "interval_unit": "MONTH",
          "interval_delay": 1
      }
  }'
Example response
{
      "id": "xicilh0vTAeZiThRtHU2Ow",
      "status": "ACTIVE",
      "account_id": "wKgFeDz5HF-BPPl08dcADQ",
      "method": {
          "type": "card",
          "number": "************4242",
          "fingerprint": "GunPelYVthifNV63LEw1",
          "card_type": "VISA",
          "exp_month": 10,
          "exp_year": 2025,
          "name": "Test Customer"
      },
      "schedule": {
          "interval_unit": "MONTH",
          "interval_delay": 1,
          "start": "2016-01-01"
      },
      "description": "Monthly recurring charge",
      "amount" : 1250,
      "currency": "USD",
      "total_occurrences": 0,
      "total_amount": 0,
      "next_payment": "2016-01-01",
      "occurrences" : [ {
          "id": "_LIG1tsDQZ21oBgPYTRJdQ",
          "amount": 1250,
          "status": "PENDING",
          "due_date": "2016-01-01",
          "attempts": 0
      } ]
  }
  
Creating a bi-weekly recurring charge from a saved bank with a maximum amount
curl -X POST -H "Content-Type:application/json" --user secret_key:  https://api.affinipay.com/v1/recurring/charges -d '
  {
      "description": "Bi-weekly recurring charge",
      "account_id": "7eyWpvRpEeKcOfUBJK8FBw",
      "amount": "1000",
      "method": "g5GCyDzaSJaHsSxmlYXCZw",
      "schedule": {
          "start": "2016-01-01",
          "interval_unit": "WEEK",
          "interval_delay": 2
      },
      "max_amount": 50000
  }'
Example response
{
      "id": "_8T2uDMQSjeU-YD_w6aAJQ",
      "status": "ACTIVE",
      "account_id": "7eyWpvRpEeKcOfUBJK8FBw",
      "method": {
          "type": "bank"
          "routing_number": "******013",
          "account_number": "**********2394",
          "account_type": "CHECKING",
          "bank_name": "FIRST BANK OF TESTING",
          "fingerprint": "U_5z8WAcO7VsoikzR7r1",
          "name": "Customer Inc",
          "account_holder_type": "business"
      },
      "schedule": {
          "interval_unit": "WEEK",
          "interval_delay": 2,
          "start": "2016-01-01"
      },
      "description": "Bi-weekly recurring charge",
      "amount": 1000,
      "currency": "USD",
      "max_amount": 50000,
      "total_occurrences": 0,
      "total_amount": 0,
      "next_payment": "2016-01-01",
      "occurrences": [ {
          "id": "MVzDNme3T3avwTm8syOZWg",
          "amount": 1000,
          "status": "PENDING",
          "due_date": "2016-01-01",
          "attempts": 0
      } ]
  }'
  

Get Recurring Charge

GET /v1/recurring/charges/{id}

A Merchant may retrieve an existing recurring_charge created through one of its own accounts by sending a GET request to /v1/recurring/charges/{id} where id is the ID of the recurring charge. The Gateway returns the JSON contents of the recurring charge.

Note: Occurrences must be retrieved separately via their own API.

Example request
curl -X GET --user secret_key: https://api.affinipay.com/v1/recurring/charges/xicilh0vTAeZiThRtHU2Ow
Example response
{
      "id": "xicilh0vTAeZiThRtHU2Ow",
      "status": "ACTIVE",
      "account_id": "wKgFeDz5HF-BPPl08dcADQ",
      "method": {
          "type": "card",
          "number": "************4242",
          "fingerprint": "GunPelYVthifNV63LEw1",
          "card_type": "VISA",
          "exp_month": 10,
          "exp_year": 2025,
          "name": "Test Customer"
      },
      "schedule": {
          "interval_unit": "MONTH",
          "interval_delay": 1,
          "start": "2016-01-01"
      },
      "description": "Monthly recurring charge",
      "amount" : 1250,
      "currency": "USD",
      "total_occurrences": 0,
      "total_amount": 0,
      "next_payment": "2016-01-01"
  }
  

Update Recurring Charge

PUT | PATCH /v1/recurring/charges/{id}

A recurring charge may be updated by sending a PUT or PATCH request to /v1/recurring/charges/{id}, substituting id for the ID of the recurring charge. A PUT request requires the complete contents of the recurring charge to be sent in the JSON request, whereas PATCH requests can send just the JSON elements that should be changed. The choice of PUT vs PATCH depends on the manner of integration. However, for PCI compliance reasons, unless saved payment methods are used to provide the payment details, a PATCH request should be used since it allows the recurring charge to be modified without needed to re-collect payment information. When updating sensitive data (card number or account number) always PATCH with a new payment token. The updated recurring charge is returned in the response content.

When a PATCH is performed that includes the method JSON hash (to update individual payment details), the type attribute of method must be specified. Refer to the example PATCH request to the right.

Update a recurring charge amount via PUT using a saved card
curl -X PUT -H "Content-Type:application/json" --user secret_key: https://api.affinipay.com/v1/recurring/charges/be0t6cgpSyGYz6cxCmAB1A -d '
  {
      "amount": "5000",
      "method": "m_bla2RHSUioRDb29imFmA",
      "schedule": {
          "start": "2016-07-01",
          "interval_unit": "MONTH",
          "interval_delay": 1
      }
  }'
Example response
{
      "id": "be0t6cgpSyGYz6cxCmAB1A",
      "status": "ACTIVE",
      "account_id": "XLu8EABYEeS91ehmSDUzYg",
      "method": {
          "type": "card",
          "number": "************4242",
          "fingerprint": "GunPelYVthifNV63LEw1",
          "card_type": "VISA",
          "exp_month": 10,
          "exp_year": 2025
      },
      "schedule": {
          "interval_unit": "MONTH",
          "interval_delay": 1,
          "start": "2016-07-01"
      },
      "amount": 5000,
      "currency": "USD",
      "total_occurrences": 0,
      "total_amount": 0,
      "next_payment": "2016-07-01"
  }
  
Update the payment method expiration date of a recurring charge via PATCH
curl -X PATCH -H "Content-Type:application/json" --user secret_key: https://api.affinipay.com/v1/recurring/charges/be0t6cgpSyGYz6cxCmAB1A -d '
  {
      "method": {
          "type": "card",
          "exp_month": 7,
          "exp_year": 2025
      }
  }'
Example response
{
      "id": "be0t6cgpSyGYz6cxCmAB1A",
      "status": "ACTIVE",
      "account_id": "XLu8EABYEeS91ehmSDUzYg",
      "method": {
          "type": "card"
          "number": "************4242",
          "fingerprint": "GunPelYVthifNV63LEw1",
          "card_type": "VISA",
          "exp_month": 7,
          "exp_year": 2025
      },
      "schedule": {
          "interval_unit": "MONTH",
          "interval_delay": 1,
          "start": "2016-07-01"
      },
      "amount": 5000,
      "currency": "USD",
      "total_occurrences": 0,
      "total_amount": 0,
      "next_payment": "2016-07-01"
  }
  

Cancel Recurring Charge

POST /v1/recurring/charges/{id}/cancel

A recurring charge may be cancelled at any time by the Merchant. Once cancelled, no further attempts are made to collect payments for the recurring charge and the status of the recurring charge is set to COMPLETED. The status_reason property is also set to user_canceled to indicate the recurring charge completed due to cancellation. Unlike deleting, cancelled recurring charges still appear in the results when listing recurring charges.

Example request
curl -X POST --user secret_key: https://api.affinipay.com/v1/recurring/charges/xicilh0vTAeZiThRtHU2Ow/cancel
Example response
{
      "id": "xicilh0vTAeZiThRtHU2Ow",
      "status": "COMPLETED",
      "status_reason": "user_canceled",
      "account_id": "wKgFeDz5HF-BPPl08dcADQ",
      "method": {
          "type": "card",
          "number": "************4242",
          "fingerprint": "GunPelYVthifNV63LEw1",
          "card_type": "VISA",
          "exp_month": 10,
          "exp_year": 2025,
          "name": "Test Customer"
      },
      "schedule": {
          "interval_unit": "MONTH",
          "interval_delay": 1,
          "start": "2016-01-01"
      },
      "description": "Monthly recurring charge",
      "amount" : 1250,
      "currency": "USD",
      "total_occurrences": 0,
      "total_amount": 0,
      "next_payment": "2016-04-01"
  }
  

Delete Recurring Charge

DELETE /v1/recurring/charges/{id}

A Merchant may delete a recurring charge by sending a DELETE to /v1/recurring/charges/{id}, substituting the ID of the recurring charge for id. Once deleted no further attempts are made to collect payments for the recurring charge and the recurring charge no longer appears when listing recurring charges for the Merchant.

Example request
curl -X DELETE --user secret_key: https://api.affinipay.com/v1/recurring/charges/pmx4nID6QtSNvB4lljqA0A
Example response
{
      "id": "pmx4nID6QtSNvB4lljqA0A",
      "status": "DELETED",
      "account_id": "wKgFeDz5HF-BPPl08dcADQ",
      ...
  }
  

List Recurring Charges

GET /v1/recurring/charges

The list of recurring_charges for a Merchant are retrieved via a GET request to /v1/recurring/charges.

The API supports pagination over the result set by allowing the client to specify the number of results per logical "page" and the page to view. The following URL parameters are supported:

ParameterDescription
pageThe page number to view, starting from 1 (optional, defaults to 1)
page_sizeThe number of results to return per logical page (optional, defaults to 20, max is 100)
account_idIf specified, only recurring charges processed through the specified account are returned; if omitted, recurring charges are returned associated with all of the Merchant's accounts.
statusThe status recurring charges must match to be returned in the results, either COMPLETED or ACTIVE. If not specified, recurring charges of both statuses are returned. Refer to the recurring_charge type definition.
referenceIf specified, only recurring charges having a matching reference are returned.
order_byA comma-separated list of properties used to sort the results. By default, the results are sorted in ascending order by the property. Each property may optionally be preceded by a '-' or '+' character to specify descending or ascending sort order. If no value is specified, the Gateway will return recurring charges in order of descending creation timestamp.
Retrieve the 5 most recent recurring charges:
curl -X GET --user secret_key: 'https://api.affinipay.com/v1/recurring/charges?page=1&page_size=5&order_by=-created'
Example response
{
      "page": 1,
      "page_size": 5,
      "total_entries": 22,
      "results": [
          {
              "id": "xicilh0vTAeZiThRtHU2Ow",
              "created": "2016-06-27T12:11:14.102Z",
              "status": "COMPLETED",
              "status_reason": "user_canceled",
              "account_id": "wKgFeDz5HF-BPPl08dcADQ",
              "method": {
                  "type": "card",
                  "number": "************4242",
                  "fingerprint": "GunPelYVthifNV63LEw1",
                  "card_type": "VISA",
                  "exp_month": 10,
                  "exp_year": 2025,
                  "name": "Test Customer"
              },
              "schedule": {
                  "interval_unit": "MONTH",
                  "interval_delay": 1,
                  "start": "2016-01-01"
              },
              "description": "Monthly recurring charge",
              "amount" : 1250,
              "currency": "USD",
              "total_occurrences": 0,
              "total_amount": 0,
              "next_payment": "2016-04-01"
          }, {
              "id": "I2h-9d8aSp-7DN-5IM9aOw",
              "created": "2016-06-27T11:35:06.823",
              "status": "ACTIVE",
              "account_id": "wKgFeDz5HF-BPPl08dcADQ",
              ...
          }, {
              "id": "3DazwIsiRsan5oVqNv1LBQ",
              "created": "2016-06-24T18:10:33.652",
              "status": "ACTIVE",
              "account_id": "XLu8EABYEeS91ehmSDUzYg",
              ...
          }, {
              "id": "PpQu1BWpTG6ancC2HUZWwQ",
              "created": "2016-06-18T14:51:27.039",
              "status": "ACTIVE",
              "account_id": "wKgFeDz5HF-BPPl08dcADQ",
              ...
          }, {
              "id": "aoeO8fBvT3KYeVYCDIrZUw",
              "created": "2016-06-16T10:41:29.520",
              "status": "COMPLETED",
              "account_id": "wKgFeDz5HF-BPPl08dcADQ",
              ...
          }
      ]
  }
  

Preview Recurring Charge

GET /v1/recurring/charges/schedule

A Merchant can preview the affects of changing dates, the number of occurrences, or both before creating a recurring charge. A recurring_charge_projection is created by sending a GET request to /v1/recurring/charges/schedule and using query parameters to define the recurring charge preview that is returned.

Query parameters

ParameterTypeDescription
occurrencesStringThe number of occurrences for the recurring charge. The default is 10. The maximum is 100.
start_dateDateThe date on which the first occurrence should occur, in the format YYYY-MM-DD. The default is the next day. (For a charge with recurrence, this value must be "today").
start_date_chargeBooleanWhether the start date for the recurring charge is today, and therefore this is a preview of a Charge with Recurrence. The default is false, meaning this is a preview of a Recurring Charge.
Preview 10 occurrences of a recurring charge, starting on August 19, 2019
curl -X GET --user secret_key: https://api.affinipay.com/v1/recurring/charges/schedule?occurrences=10&start_date=2019-8-19 -d '{
    "amount":1250,
    "max_occurrences": 20,
    "max_amount":10000,
    "schedule":{
       "interval_unit":"WEEK",
        "interval_delay":"1",
       "days":["1","5"],
       "start":"2019-8-19"
    }
  }'
Example response
{
    "amount": 1250,
    "max_occurrences": 20,
    "max_amount": 10000,
    "total_occurrences": 0,
    "total_amount": 0,
    "remaining_occurrences": 8,
    "remaining_amount": 10000,
    "schedule": {
        "interval_unit": "WEEK",
        "interval_delay": 1,
        "start": "2019-08-19",
        "days": [
            "1",
            "5"
        ]
    },
    "next_payment": "2019-08-19",
    "occurrences": [
        {
            "amount": 1250,
            "due_date": "2019-08-19"
        },
        {
            "amount": 1250,
            "due_date": "2019-08-23"
        },
        {
            "amount": 1250,
            "due_date": "2019-08-26"
        },
        {
            "amount": 1250,
            "due_date": "2019-08-30"
        },
        {
            "amount": 1250,
            "due_date": "2019-09-02"
        },
        {
            "amount": 1250,
            "due_date": "2019-09-06"
        },
        {
            "amount": 1250,
            "due_date": "2019-09-09"
        },
        {
            "amount": 1250,
            "due_date": "2019-09-13"
        }
    ]
}
  

Get Occurrence

GET /v1/recurring/charges/{id}/occurrences/{occurrenceId}

An individual recurring_charge_occurrence is retrieved by performing a GET request to /v1/recurring/charges/{id}/occurrences/{occurrenceId}, where id is the ID of the owning recurring charge and occurrenceId is the ID of the occurrence to retrieve.

Example request
curl -X GET --user secret_key: https://api.affinipay.com/v1/recurring/charges/xicilh0vTAeZiThRtHU2Ow/occurrences/_LIG1tsDQZ21oBgPYTRJdQ
Example response
{
      "id": "_LIG1tsDQZ21oBgPYTRJdQ",
      "recurring_charge_id": "xicilh0vTAeZiThRtHU2Ow",
      "amount": 1250,
      "status": "PAID",
      "due_date": "2016-01-01",
      "attempts": 1,
      "last_attempt": "2016-06-27T19:23:49.422Z",
      "transactions": [ {
          "id": "UvGF3iMEQwObZN0hxikByg",
          "type": "CHARGE"
          "account_id": "_gpv9uWxEeOajNb7ZxMrnA",
          "status": "AUTHORIZED",
          "auto_capture": true,
          "amount": 1250,
          "currency": "USD",
          "method": {
              "type": "card"
              "number": "************4242",
              "fingerprint": "GunPelYVthifNV63LEw1",
              "card_type": "VISA",
              "exp_month": 10,
              "exp_year": 2025,
              "name": "Test Customer"
          },
          "amount_refunded": 0,
          "authorization_code": "R9IFPH",
          "recurring_charge_id": "xicilh0vTAeZiThRtHU2Ow",
          "recurring_charge_occurrence_id": "_LIG1tsDQZ21oBgPYTRJdQ"
      } ]
  }
  

Pay Occurrence

POST /v1/recurring/charges/{id}/occurrences/{occurrenceId}/pay

A Merchant may pre-pay an recurring_charge_occurrence (attempting to collect payment in advance of the scheduled due date, at which time the Gateway would automatically attempt to collect payment) or re-try a previously ignored or failed payment by issuing an empty POST to /v1/recurring/charges/{id}/occurrences/{occurrenceId}/pay, substituting the ID of the owning recurring charge for id and the ID of the occurrence to pay for occurrenceId.

Example request
curl -X POST --user secret_key: https://api.affinipay.com/v1/recurring/charges/xicilh0vTAeZiThRtHU2Ow/occurrences/_LIG1tsDQZ21oBgPYTRJdQ/pay
Example response
{
      "id": "_LIG1tsDQZ21oBgPYTRJdQ",
      "recurring_charge_id": "xicilh0vTAeZiThRtHU2Ow",
      "amount": 1250,
      "status": "PAID",
      "due_date": "2016-01-01",
      "attempts": 1,
      "last_attempt": "2016-06-27T19:23:49.422Z",
      "transactions": [ {
          "id": "UvGF3iMEQwObZN0hxikByg",
          "type": "CHARGE"
          "account_id": "_gpv9uWxEeOajNb7ZxMrnA",
          "status": "AUTHORIZED",
          "auto_capture": true,
          "amount": 1250,
          "currency": "USD",
          "method": {
              "type": "card"
              "number": "************4242",
              "fingerprint": "GunPelYVthifNV63LEw1",
              "card_type": "VISA",
              "exp_month": 10,
              "exp_year": 2025,
              "name": "Test Customer"
          },
          "amount_refunded": 0,
          "authorization_code": "R9IFPH",
          "recurring_charge_id": "xicilh0vTAeZiThRtHU2Ow",
          "recurring_charge_occurrence_id": "_LIG1tsDQZ21oBgPYTRJdQ"
      } ]
  }
  

Ignore Occurrence

POST /v1/recurring/charges/{id}/occurrences/{occurrenceId}/ignore

A Merchant may optionally mark an recurring_charge_occurrence of a recurring charge as ignored, provided the occurrence has not already been paid. This will prevent the Gateway from attempting to collect payment for this specific occurrence of the schedule. This mechanism can be used to handle scenarios in which a customer uses an alternative mechanism to make a payment (for example, sending a check) or a Merchant wishes to forgo a payment. Occurrences marked ignored can still be collected at a later time using the Pay Occurrence endpoint.

Example request
curl -X POST --user secret_key: https://api.affinipay.com/v1/recurring/charges/xicilh0vTAeZiThRtHU2Ow/occurrences/Vj91nLgbSg61pzHqYb06VQ/ignore
Example response
{
      "id": "Vj91nLgbSg61pzHqYb06VQ",
      "recurring_charge_id": "xicilh0vTAeZiThRtHU2Ow",
      "amount": 1250,
      "status": "IGNORED",
      "due_date": "2016-02-01",
      "attempts": 0
  }
  

List Occurrences

GET /v1/recurring/charges/{id}/occurrences

The list of recurring_charge_occurrences for a recurring charge, including status information and associated transactions, is obtained by sending a GET request to /v1/recurring/charges/{id}/occurrences, substituting the recurring charge ID for id. The Gateway responds with a search_results instance containing the occurrences.

Note: Occurrences are returned in descending order of their creation such that the next pending due occurrence (or the last occurrence in a completed schedule) is first.

The API supports pagination over the result set by allowing the client to specify the number of results per logical "page" and the page to view. The following URL parameters are supported:

ParameterDescription
pageThe page number to view, starting from 1 (optional, defaults to 1)
page_sizeThe number of results to return per logical page (optional, defaults to 20, max is 100)
Example request
curl -X GET --user secret_key: https://api.affinipay.com/v1/recurring/charges/xicilh0vTAeZiThRtHU2Ow/occurrences
Example response
{
      "page": 1,
      "page_size": 20,
      "total_entries": 3,
      "results" : [ {
          "id": "D_NjpMyqSMiqufQxEYQ0lA",
          "recurring_charge_id": "xicilh0vTAeZiThRtHU2Ow",
          "amount": 1250,
          "status": "PENDING",
          "due_date": "2016-03-01",
          "attempts": 0
      }, {
          "id": "Vj91nLgbSg61pzHqYb06VQ",
          "recurring_charge_id": "xicilh0vTAeZiThRtHU2Ow",
          "amount": 1250,
          "status": "IGNORED",
          "due_date": "2016-02-01",
          "attempts": 0
      }, {
          "id": "_LIG1tsDQZ21oBgPYTRJdQ",
          "recurring_charge_id": "xicilh0vTAeZiThRtHU2Ow",
          "amount": 1250,
          "status": "PAID",
          "due_date": "2016-01-01",
          "attempts": 1,
          "last_attempt": "2016-06-27T19:23:49.422Z",
          "transactions": [ {
              "id": "UvGF3iMEQwObZN0hxikByg",
              "type": "CHARGE"
              "account_id": "_gpv9uWxEeOajNb7ZxMrnA",
              "status": "AUTHORIZED",
              "auto_capture": true,
              "amount": 1250,
              "currency": "USD",
              "method": {
                  "type": "card"
                  "number": "************4242",
                  "fingerprint": "GunPelYVthifNV63LEw1",
                  "card_type": "VISA",
                  "exp_month": 10,
                  "exp_year": 2025,
                  "name": "Test Customer"
              },
              "amount_refunded": 0,
              "authorization_code": "R9IFPH",
              "recurring_charge_id": "xicilh0vTAeZiThRtHU2Ow",
              "recurring_charge_occurrence_id": "_LIG1tsDQZ21oBgPYTRJdQ"
          } ]
      } ]
  }
  

Payment Methods

Merchant systems which integrate into the Gateway to provide customer payment pages need the ability to collect customer credit card and banking information and then pass that data through their own system to the Gateway's transaction APIs. In order to avoid ever having to store sensitive card details on the Merchant systems, the Gateway provides several means of generating payment methods in exchange for payment details. Payment methods obscure the sensitive aspects of the payment details while providing an ID that may be used in any API that accepts card or bank details, in lieu of the card or bank JSON entity.

The Gateway offers two types of payment methods: saved and one-time. Saved payment methods offer a managed mechanism supporting multiple payments over time. Merchant users can save both cards and banks for use in any transaction API which accepts a payment method.

Saved payment methods are typically integrated into a Merchant site to support "remembered" payment details for customers. For example, the site might allow a user to save credit card information for a future purchase on the site. The site exchanges the credit card details for a card (either directly via the API, or using a payment form to generate a token, and then exchanging the token for a Card). When the user chooses the saved payment method for a future purchase, the site need only send the payment request with the saved Card ID returned from the Gateway.

If you want to save payment details for future use, create a PaymentMethod rather than a saved card or saved bank. PaymentMethods can be used in AffiniPay’s Card Vault and are associated with a particular payer (a Contact).

One-time tokens are designed to simplify payment form integration with the Gateway. The Merchant system need only provide an HTML form using hosted fields that collects the necessary payment details. The page can then interact directly with the Gateway, exchanging the payment details for a token. Alternatively, the Merchant page can use our redirect mechanism for a completely JavaScript-free interaction with the Gateway. Using either mechanism, the merchant system receives a one-time token which can then be safely stored and passed to the Gateway API when the Charge or Refund is to be performed.

One-time tokens are designed for single use, after which they are deleted from the Gateway. Unused one-time tokens are deleted automatically 5 minutes after creation.

Saved Cards

Merchant systems can use the saved card APIs to provide secure storage of "remembered" credit cards for a customer for use in future transactions.

Store a Card

POST /v1/cards

If you want to save payment details for future use, create a PaymentMethod rather than a saved card or saved bank. PaymentMethods can be used in AffiniPay’s Card Vault and are associated with a particular payer (a Contact).

A merchant creates a saved card on behalf of a user, for use in future payments, by POSTing the card details to /v1/cards. Alternatively, a previously created token ID can be provided to convert the token into a saved card. The saved card JSON is returned.

Following a FORM POST to create a token, the id property of the returned token JSON can be used as the value of a Card token_id to convert the token into a saved card.

Creating a saved card
curl -X POST -H "Content-Type:application/json" --user secret_key: https://api.affinipay.com/v1/cards -d '
  {
      "number": "4242424242424242",
      "exp_month": 10,
      "exp_year": 2025,
      "name": "Some Customer",
      "description": "Corporate VISA",
      "reference": "Customer123"
  }'
Example response
{
      "id": "RNZyuzAPTK2TSS6hPKafDA",
      "type": "card",
      "reference": "Customer123",
      "description": "Corporate VISA",
      "name": "Some Customer",
      "number": "************4242",
      "fingerprint": "GunPelYVthifNV63LEw1",
      "card_type": "VISA",
      "exp_month": 10,
      "exp_year": 2025
  }
  
Creating a saved card from a one-time token
curl -X POST -H "Content-Type:application/json" --user secret_key: https://api.affinipay.com/v1/cards -d '
  {
      "token_id": "lUi5VesmStiZo0ss5I0t5w"
  }'
Example response
{
      "id": "iwinxWe9T_OXinD5oOqYBQ",
      "type": "card",
      "name": "Some Customer",
      "number": "************4242",
      "fingerprint": "GunPelYVthifNV63LEw1",
      "card_type": "VISA",
      "exp_month": 10,
      "exp_year": 2025
  }
  
Charging using the saved card
curl -X POST -H "Content-Type:application/json" --user secret_key: https://api.affinipay.com/v1/charges -d '
  {
      "amount": "110",
      "method": "RNZyuzAPTK2TSS6hPKafDA"
  }'
Example response
{
      "id": "zMToetuTSC2KlIZmJEYr8Q",
      "type": "CHARGE",
      "account_id": "SrxWOANuEeO2jfIPcQrePg",
      "status": "AUTHORIZED",
      "amount": 110,
      "currency": "USD",
      "auto_capture": true,
      "amount_refunded": 0,
      "method": {
          "type": "card",
          "name": "Some Customer",
          "number": "************4242",
          "fingerprint": "GunPelYVthifNV63LEw1",
          "card_type": "VISA",
          "exp_month": 10,
          "exp_year": 2025
      }
  }
Updating a saved card with a one-time token
curl -X POST -H "Content-Type:application/json" --user secret_key: https://api.affinipay.com/v1/cards -d '
  {
      "token_id": "quDARdEUSZWW9C3OC42E1A"
  }'
Example response
{
      "id": "QtlpcMpsQHSuQv11E5KEbQ",
      "created": "2019-04-18T16:17:00.059Z",
      "modified": "2019-04-18T16:17:00.059Z",
      "address1": "123 memory lane",
      "city": "Houston",
      "state": "Texas",
      "postal_code": "78746",
      "type": "card",
      "number": "************4242",
      "fingerprint": "GunPelYVthifNV63LEw1",
      "card_type": "VISA",
      "exp_month": 12,
      "exp_year": 2025
  }

Update a Card

PATCH /v1/cards/{cardId}

A Merchant can update any details in a saved card on behalf of a user by PATCHing the updated card details to /v1/cards/{cardId}. When updating the card number, expiration month, or expiration year, PATCH the card using a token that contains the updated data.

Updating the reference for a saved card
curl -X PATCH -H "Content-Type:application/json" --user secret_key: https://api.affinipay.com/v1/cards/RNZyuzAPTK2TSS6hPKafDA -d '
  {
      "reference": "Case 123"
  }'
Example response
{
      "id": "RNZyuzAPTK2TSS6hPKafDA",
      "type": "card",
      "reference": "Case 123",
      "description": "Corporate VISA",
      "name": "Some Customer",
      "number": "************1881",
      "fingerprint": "8hIJ53YVthis5I63LfNV",
      "card_type": "VISA",
      "exp_month": 11,
      "exp_year": 2025
  } 
Updating card number only with token
curl -X PATCH -H "Content-Type:application/json" --user secret_key: https://api.affinipay.com/v1/cards/RNZyuzAPTK2TSS6hPKafDA -d '
  {
      "token_id": "iCKjHy2SS4GhuZzW0aU5Pw"
  }'
Example response
{
      "id": "RNZyuzAPTK2TSS6hPKafDA",
      "type": "card",
      "reference": "Case 123",
      "description": "Corporate VISA",
      "name": "Some Customer",
      "number": "************2478",
      "fingerprint": "8hIJ53YVthis5I63LfNV",
      "card_type": "VISA",
      "exp_month": 11,
      "exp_year": 2025
  }

  

Get a Card

GET /v1/cards/{cardId}

A previously saved card can be retrieved by sending a GET to /v1/cards/{cardId}, substituting the ID of the card. The Gateway responds with the JSON representation of the card with sensitive properties masked.

Example request
curl -X GET --user secret_key: https://api.affinipay.com/v1/cards/RNZyuzAPTK2TSS6hPKafDA
{
      "id": "RNZyuzAPTK2TSS6hPKafDA",
      "type": "card",
      "reference": "Customer123",
      "description": "Corporate VISA",
      "name": "Some Customer",
      "number": "************4242",
      "fingerprint": "GunPelYVthifNV63LEw1",
      "card_type": "VISA",
      "exp_month": 10,
      "exp_year": 2025
  }
  

Delete a Card

DELETE /v1/cards/{cardId}

A previously saved card can be deleted by sending a DELETE to /v1/cards/{cardId}, substituting the ID of the card. The Gateway responds with the JSON representation of the deleted card with sensitive properties masked. After deletion, the card ID can no longer be used to perform payments.

Example request
curl -X DELETE --user secret_key: https://api.affinipay.com/v1/cards/RNZyuzAPTK2TSS6hPKafDA
Example resonse
{
      "id": "RNZyuzAPTK2TSS6hPKafDA",
      "type": "card",
      "reference": "Customer123",
      "description": "Corporate VISA",
      "name": "Some Customer",
      "number": "************4242",
      "fingerprint": "GunPelYVthifNV63LEw1",
      "card_type": "VISA",
      "exp_month": 10,
      "exp_year": 2025
  }
  

List Cards

GET /v1/cards

The list of cards saved for a merchant are retrieved via a GET request to /v1/cards.

The API supports pagination over the result set by allowing the client to specify the number of results per logical "page" and the page to view. The following URL parameters are supported:

ParameterDescription
pageThe page number to view, starting from 1 (optional, defaults to 1)
page_sizeThe number of results to return per logical page (optional, defaults to 20, max is 100)
referenceReturns only Cards having the given reference value (optional)
exp_monthReturns Cards for which the expiration month matches the given value (optional)
exp_yearReturns Cards for which the expiration year matches the given value (optional)
The second example makes use of the reference property on saved cards to support retrieving cards for a specific customer having the ID Customer123 within the integrating merchant system. A merchant can query the Gateway to find which customers' saved cards are expiring in a given month and year in order to support collection of updated payment information. The exp_month and exp_year query parameters are specified with the desired expiration month and year.
Retrieve the first page of saved cards
curl -X GET --user secret_key: 'https://api.affinipay.com/v1/cards?page=1&page_size=5'
Example response
{
      "page": 1,
      "page_size": 5,
      "total_entries": 24,
      "results": [
          {
              "id": "JimubYg3TXyYpETqP2c_rg",
              "type": "card",
              "description": "A description for this card",
              "reference": "Customer123",
              "name": "Sample Customer",
              "address1": "123 Main St",
              "postal_code": "78730",
              "number": "************4242",
              "fingerprint": "GunPelYVthifNV63LEw1",
              "card_type": "VISA",
              "exp_month": 10,
              "exp_year": 2025
          }, {
              "id": "narZ3f_9TQGcjm4ZMAAI5g",
              ...
          }, {
              "id": "aXfXI1j9Tm-zG5u4WrgNRw",
              ....
          }, {
              "id": "13ZQq2qGQHuJ2fm7qXtvoQ",
              ...
          }, {
              "id": "AjaY-FpwQY2ISxSwE04Z4g",
              "type": "card",
              "number": "************8356",
              "fingerprint": "AAV45s0hY9wezAf4tuo6",
              "card_type": "VISA",
              "exp_month": 3,
              "exp_year": 2025
          }
      ]
  }
  
Retrieve saved cards for a specific customer
curl -X GET --user secret_key: https://api.affinipay.com/v1/cards?reference=Customer123
Example response
{
      "page": 1,
      "page_size": 20,
      "total_entries": 1,
      "results": [
          {
              "id": "JimubYg3TXyYpETqP2c_rg",
              "type": "card",
              "description": "A description for this card",
              "reference": "Customer123",
              "name": "Sample Customer",
              "address1": "123 Main St",
              "postal_code": "78730",
              "number": "************4242",
              "fingerprint": "GunPelYVthifNV63LEw1",
              "card_type": "VISA",
              "exp_month": 10,
              "exp_year": 2025
          }
      ]
  }
  
Retrieve saved cards by expiration
curl -X GET --user secret_key: https://api.affinipay.com/v1/cards?exp_month=3&exp_year=2025
Example response
{
      "page": 1,
      "page_size": 20,
      "total_entries": 1,
      "results": [
          {
              "id": "AjaY-FpwQY2ISxSwE04Z4g",
              "type": "card",
              "number": "************8356",
              "fingerprint": "AAV45s0hY9wezAf4tuo6",
              "card_type": "VISA",
              "exp_month": 3,
              "exp_year": 2025
          }
      ]
  }
  

Saved Banks

The saved bank object provides functionality for merchant systems to securely store "remembered" bank information for use as payment methods in the Transactions endpoints.

Store a Bank

POST /v1/banks

If you want to save payment details for future use, create a PaymentMethod rather than a saved card or saved bank. PaymentMethods can be used in AffiniPay’s Card Vault and are associated with a particular payer (a Contact).

A Merchant creates a saved bank on behalf of a user by POSTing the bank details to /v1/banks. Alternatively, a previously created token ID can be provided to convert the token into a saved Bank. The saved bank JSON is returned.

Creating a saved bank
curl -X POST -H "Content-Type:application/json" --user secret_key: https://api.affinipay.com/v1/banks -d '
  {
      "routing_number": "000000013",
      "account_number": "10333257392394",
      "account_type": "CHECKING",
      "name": "Customer Inc",
      "account_holder_type": "business",
      "description": "Corporate Checking",
      "reference": "Customer123"
  }'
Example response
{
      "id": "vU42KZWhTd2iiGLhjfJR6A",
      "type": "bank",
      "description": "Corporate Checking",
      "reference": "Customer123",
      "name": "Customer Inc",
      "account_holder_type": "business",
      "routing_number": "******013",
      "account_number": "**********2394",
      "account_type": "CHECKING",
      "fingerprint": "j_RBZuzITtssQF8dhRvs",
      "bank_name": "FIRST BANK OF TESTING"
  }
  
Charging a customer using the saved bank
curl -X POST -H "Content-Type:application/json" --user secret_key: https://api.affinipay.com/v1/charges -d '
  {
      "amount": "41099",
      "method": "vU42KZWhTd2iiGLhjfJR6A"
  }'
Example response
{
      "id": "ezpET0X4TNmj1DVf7IkS2Q",
      "type": "CHARGE",
      "account_id": "SryXugNuEeO2jfIPcQrePg",
      "status": "AUTHORIZED",
      "amount": 41099,
      "currency": "USD",
      "method": {
          "type": "bank",
          "routing_number": "******013",
          "account_number": "**********2394",
          "account_type": "CHECKING",
          "fingerprint": "j_RBZuzITtssQF8dhRvs",
          "bank_name": "FIRST BANK OF TESTING",
          "name": "Customer Inc",
          "account_holder_type": "business"
      }
  }
Updating a saved bank with a one-time token
curl -X POST -H "Content-Type:application/json" --user secret_key: https://api.affinipay.com/v1/banks -d '
  {
      "token_id": "ddPKiGvbTzu7J_MOMgS_xQ"
  }'
Example response
{
      "id": "DKHlG78LS8igJxgpqCbA_w",
      "created": "2019-04-18T15:57:53.555Z",
      "modified": "2019-04-18T15:57:53.555Z",
      "reference": "Customer123",
      "description": "Corporate Checking",
      "bank_name": "FIRST BANK OF TESTING",
      "name": "Customer Inc",
      "account_holder_type": "business",
      "type": "bank",
      "routing_number": "******013",
      "account_number": "**********2394",
      "account_type": "CHECKING",
      "fingerprint": "U_5z8WAcO7VsoikzR7r1"
  }

Update a Bank

PATCH /v1/banks/{bankId}

A Merchant can update a saved bank on behalf of a user by PATCHing the bank details to /v1/banks/{bankId}. When updating the routing number or account number, PATCH the bank using a token that contains the updated data.

Updating the description
curl -X PATCH -H "Content-Type:application/json" --user secret_key: https://api.affinipay.com/v1/banks/vU42KZWhTd2iiGLhjfJR6A -d '
  {
      "description": "Primary Checking"
  }'
Example response
{
      "id": "vU42KZWhTd2iiGLhjfJR6A",
      "type": "bank",
      "description": "Primary Checking",
      "reference": "Customer123",
      "name": "Customer Inc",
      "account_holder_type": "business",
      "routing_number": "******013",
      "account_number": "**********9999",
      "account_type": "CHECKING",
      "fingerprint": "j_RBZuzITtssQF8dhRvs",
      "bank_name": "FIRST BANK OF TESTING"
  }
  
Updating the account number with a token
curl -X PATCH -H "Content-Type:application/json" --user secret_key: https://api.affinipay.com/v1/banks/vU42KZWhTd2iiGLhjfJR6A -d '
  {
      "token_id": "uR934Nmj03Qqp48c76vVvi"
  }'
Example response
{
      "id": "vU42KZWhTd2iiGLhjfJR6A",
      "type": "bank",
      "description": "Primary Checking",
      "reference": "Customer123",
      "name": "Customer Inc",
      "account_holder_type": "business",
      "routing_number": "******013",
      "account_number": "**********6389",
      "account_type": "CHECKING",
      "fingerprint": "k_0tOjUcO7VsoikpqU54",
      "bank_name": "FIRST BANK OF TESTING"
  }
  

Get a Bank

GET /v1/banks/{bankId}

A previously saved bank can be retrieved by sending a GET to /v1/banks/{bankId}, substituting the ID of the Bank. The Gateway responds with the JSON representation of the bank with sensitive properties masked.

Example request
curl -X GET --user secret_key: https://api.affinipay.com/v1/banks/vU42KZWhTd2iiGLhjfJR6A
Example response
{
      "id": "vU42KZWhTd2iiGLhjfJR6A",
      "type": "bank",
      "description": "Corporate Checking",
      "reference": "Customer123",
      "name": "Customer Inc",
      "account_holder_type": "business",
      "routing_number": "******013",
      "account_number": "**********2394",
      "account_type": "CHECKING",
      "fingerprint": "j_RBZuzITtssQF8dhRvs",
      "bank_name": "FIRST BANK OF TESTING"
  }
  

Delete a Bank

DELETE /v1/banks/{bankId}

A previously saved bank can be deleted by sending a DELETE to /v1/banks/{bankId}, substituting the ID of the bank. The Gateway responds with the JSON representation of the deleted bank with sensitive properties masked. After deletion, the bank ID can no longer be used to perform payments.

Example request
curl -X DELETE --user secret_key: https://api.affinipay.com/v1/banks/vU42KZWhTd2iiGLhjfJR6A
Example response
{
      "id": "vU42KZWhTd2iiGLhjfJR6A",
      "type": "bank",
      "description": "Corporate Checking",
      "reference": "Customer123",
      "name": "Customer Inc",
      "account_holder_type": "business",
      "routing_number": "******013",
      "account_number": "**********2394",
      "account_type": "CHECKING",
      "fingerprint": "j_RBZuzITtssQF8dhRvs",
      "bank_name": "FIRST BANK OF TESTING"
  }
  

List Banks

GET /v1/banks

The list of banks saved for a merchant are retrieved via a GET request to /v1/banks.

The API supports pagination over the result set by allowing the client to specify the number of results per logical "page" and the page to view. The following URL parameters are supported:

ParameterDescription
pageThe page number to view, starting from 1 (optional, defaults to 1)
page_sizeThe number of results to return per logical page (optional, defaults to 20, max is 100)
referenceReturns only Banks having the given reference value (optional)

The second example makes use of the reference property on saved Banks to support retrieving Banks for a specific customer having the ID Customer123 within the integrating merchant system.

Retrieve the third page of saved banks, with four items per page
curl -X GET --user secret_key: 'https://api.affinipay.com/v1/banks?page=3&page_size=4'
Example response
{
      "page": 3,
      "page_size":4,
      "total_entries": 61,
      "results": [
          {
              "id": "vU42KZWhTd2iiGLhjfJR6A",
              "type": "bank",
              "description": "Corporate Checking",
              "reference": "Customer123",
              "name": "Customer Inc",
              "account_holder_type": "business"
              "routing_number": "******013",
              "account_number": "**********2394",
              "account_type": "CHECKING",
              "fingerprint": "j_RBZuzITtssQF8dhRvs",
              "bank_name": "FIRST BANK OF TESTING"
          }, {
              "id": "TAvupZVpR4m7zO8L-tcDRQ",
              ...
          }, {
              "id": "	_jvTVhl5T_m57XC-H2f9rA",
              ...
          }, {
              "id": "VrjnCzB8QL6MFH-2OVLjFA",
              "type": "bank",
              "name": "Customer Ltd",
              "account_holder_type": "business"
              "routing_number": "******000",
              "account_number": "*********3847",
              "account_type": "SAVINGS",
              "fingerprint": "VYPocmxwclCWM4vcdLcW",
              "bank_name": "TEST FEDERAL CREDIT UNION"
          }
      ]
  }
  
Retrieve saved banks for a specific customer
curl -X GET --user secret_key: https://api.affinipay.com/v1/banks?reference=Customer123
  
Example response
{
      "page": 1,
      "page_size": 20,
      "total_entries": 1,
      "results": [
          {
              "id": "vU42KZWhTd2iiGLhjfJR6A",
              "type": "bank",
              "description": "Corporate Checking",
              "reference": "Customer123",
              "name": "Some Customer",
              "routing_number": "******013",
              "account_number": "**********2394",
              "account_type": "CHECKING",
              "fingerprint": "j_RBZuzITtssQF8dhRvs",
              "bank_name": "FIRST BANK OF TESTING"
          }
      ]
  }
  

One-Time Tokens

The following endpoints support creating and retrieving tokens for use integrating merchant payment pages with the Gateway.

Note: CORS is allowed for calls to the /v1/tokens endpoint, but it will cause errors when used in association with any other API endpoint.

Create a Token

POST /v1/tokens

A merchant system, having collected a customer's payment details, may exchange them for a one-time payment token by POSTing the payment details to /v1/tokens. One-time tokens expire five minutes after creation.

The Gateway responds with a JSON token containing the payment details (with the card number, routing number, and bank account number masked, and without the given CVV, if any), the key id holding the token identifier to be sent in a future transaction, and any additional data included in the POST. The Gateway accepts payment details as either form URL-encoded data or a JSON structure, based on the HTTP Content-Type header provided (application/x-www-form-urlencoded or application/json, respectively).

This endpoint only requires the merchant public key for authentication in order to support generating tokens directly from merchant web pages. The merchant public key can be specified as a form POST parameter, rather than using the HTTP basic authorization header, to support generation of tokens from form POSTs without JavaScript.

Note: You should never use your secret keys in any location, such as a web page, that might be accessible without proper authorization and access controls.

For payment form flows using HTTP redirects (as opposed to JavaScript) with form URL-encoded data, specifying a redirect_url will cause the Gateway to return an HTTP 303 redirecting to the location specified, along with the generated token ID as a query parameter (token_id). The location is usually the merchant system URL that processes a payment request. This is optional.

Create a credit card one-time token using form URL-encoding
curl -X POST -H "Content-Type:application/x-www-form-urlencoded" --user public_key: https://api.affinipay.com/v1/tokens -d 'type=card&number=4242424242424242&exp_month=10&exp_year=2025&cvv=123&extra_data=some_value&extra_data=second_value&more_data=another_value'
Example response
{
      "id": "wKgFaj72F3aBPvZneEsBew",
      "type": "card",
      "number": "************4242",
      "fingerprint": "GunPelYVthifNV63LEw1",
      "exp_month": 10,
      "exp_year": 2025,
      "cvv": "***",
      "form_data": {
          "extra_data": [ "some_value", "second_value" ],
          "more_data": "another_value"
      }
  }
  
Create a credit card one-time token using JSON encoding
curl -X POST -H "Content-Type:application/json" --user public_key: https://api.affinipay.com/v1/tokens -d '
  {
    "type": "card",
    "number": "4242424242424242",
    "exp_month": 10,
    "exp_year": 2025,
    "cvv": "123",
    "form_data": {
        "extra_data": "some_value",
        "more_data": "another_value"
    }
}'
Example response
{
      "id": "wKgFaj72F3aBPvZneEsBew",
      "type": "card",
      "number": "************4242",
      "fingerprint": "GunPelYVthifNV63LEw1",
      "exp_month": 10,
      "exp_year": 2025,
      "cvv": "***",
      "form_data": {
          "extra_data": [ "some_value", "second_value" ],
          "more_data": "another_value"
      }
  }
  
Create a bank one-time token specifying a redirect URL
curl -X POST -H "Content-Type:application/x-www-form-urlencoded" --user public_key: https://api.affinipay.com/v1/tokens -d 'type=bank&routing_number=000000013&account_number=1234567890&account_type=CHECKING&redirect_url=https://merchant.example.com/payment'
Example response
HTTP/1.1 303 See Other Location: https://merchant.example.com/payment?token_id=wKgFaj72F3aBPvZ9KuIBfAContent-Length: 0
  

Get a Token

GET /v1/tokens/{tokenId}

An existing payment token may be retrieved by performing a GET to /v1/tokens/{tokenId} where tokenId is the ID of a payment token created previously by the merchant. The API returns a JSON representation of the token, with all sensitive data masked.

When used with a redirect-based payment form, this API can be used to re-populate payment forms with the customer's data following a submitted transaction that is rejected, for example, due to validation errors.

Example request
curl -X GET --user secret_key: https://api.affinipay.com/v1/tokens/wKgFaj72F3aBPvZneEsBew
Example response
{
      "id": "wKgFaj72F3aBPvZneEsBew",
      "type": "card",
      "number": "************4242",
      "exp_month": 12,
      "exp_year": 2025,
      "cvv": "***",
      "name": "Some User",
      "address1": "123456",
      "postal_code": "78730"
  }
  

Events

Important changes to data within the Gateway are recorded as events. Event data can be retrieved on demand using the Get Event by ID and List Events endpoints. Alternatively, events can be delivered to one or more URLs using an HTTP POST through the Gateway's webhooks. There are several types of events available.

Event URLs should represent endpoints you control and that are capable of handling events. AffiniPay expects HTTP status codes in response to webhooks. If your server doesn't respond with a 200 OK message after receiving an event, AffiniPay's attempts to resend the event depend on the event type:

  • Affinipay Payment Gateway events. Retried up to 6 times, with an initial 1-hour delay that increases by 1 hour for each failed attempt. (For example, first attempt at time t0, second attempt at t0 + 1 hour, third attempt at t0 + 2 hours, and so on.)
  • Partner OAuth application events (such as merchant application events). Retried once every 10 minutes for a maximum of 25 attempts.

Note: Events don't contain any sensitive payment details, but they may contain personally identifiable information like customer names and addresses. For this reason, we strongly recommend using the HTTPS scheme for all webhook URLs you register.

Get Event by ID

GET /v1/events/{eventId}

The content of an individual event is retrieved by performing a GET to /v1/events/{eventId} where eventId is the ID of the event. The Gateway returns a JSON event element identifying the type of event, when it was created, and the event data.

Example request
curl -X GET --user secret_key: https://api.affinipay.com/v1/events/gUoRi3NSTvGNjmNTip6pCw
Example response
{
      "id" : "DYEDsGU_RgWjwnY5cTPMew",
      "created" : "2016-10-25T17:41:41.959Z",
      "type" : "transaction.authorized",
      "data" : {
        "id" : "m7wPNJgUT4uHNRoSdUpTnA",
        "created" : "2016-10-25T17:41:41.938Z",
        "modified" : "2016-10-25T17:41:41.938Z",
        "account_id" : "8IO47jzCEeOfvhLxg70sog",
        "status" : "AUTHORIZED",
        "amount" : 100,
        "currency" : "USD",
        "auto_capture" : true,
        "amount_refunded" : 0,
        "authorization_code": "H3PKFH",
        "type" : "CHARGE",
        "method" : {
          "name" : "Some Customer",
          "address1" : "123 Main",
          "postal_code" : "78730",
          "type" : "card",
          "number" : "************4242",
          "fingerprint" : "GunPelYVthifNV63LEw1",
          "card_type" : "VISA",
          "exp_month" : 10,
          "exp_year" : 2025,
          "cvv" : "***"
        }
      }
  }
  

List Events

GET /v1/events

The events associated with the authenticated Merchant are returned via a GET request to /v1/events.

The API supports pagination over the result set by allowing the client to specify the number of results per logical "page" and the page to view.

By default the Events are returned in reverse chronological order, such that the most recent Events appear first. However, if the start_date parameter is specified, only events occurring after the given timestamp are returned, and the results are returned in chronological order. Start date-based retrieval is intended to simplify synchronization of Gateway state with external systems.

ParameterDescription
pageThe page number to view, starting from 1 (optional, defaults to 1)
page_sizeThe number of results to return per logical page (optional, defaults to 20, max is 1000)
start_dateOnly events created after the specified date/time are returned. The timestamp must be in the format yyyy-MM-dd'T'HH:mm:ss.SSS'Z'. All events are returned by default.
Retrieve the 2 most recent events
curl -X GET --user secret_key: 'https://api.affinipay.com/v1/events?page=1&page_size=2'
Example response
{
      "page": 1,
      "page_size": 2,
      "total_entries": 736,
      "results": [
          {
              "id": "LhBgkp4oScmr3wEeyHKzZw",
              "created": "2016-10-25T17:46:33.792Z",
              "type": "transaction.authorized",
              "data": {
                  "id": "AfLZQYR2RLGRqBxDo4IKIQ",
                  "created": "2016-10-25T17:46:33.786Z",
                  "modified": "2016-10-25T17:46:33.786Z",
                  "account_id": "8IO47jzCEeOfvhLxg70sog",
                  "status": "AUTHORIZED",
                  "amount": 100,
                  "currency": "USD",
                  "auto_capture": true,
                  "amount_refunded": 0,
                  "authorization_code": "U2QF6A",
                  "type": "CHARGE",
                  "method": {
                      "name": "Some Customer",
                      "address1": "123 Main St",
                      "postal_code": "78730",
                      "type": "card",
                      "number": "************4242",
                      "fingerprint": "GunPelYVthifNV63LEw1",
                      "card_type": "VISA",
                      "exp_month": 10,
                      "exp_year": 2025,
                      "cvv": "***"
                  }
              }
          }, {
              "id": "L6vN5PwhRDG9SDKxDwghJQ",
              "created": "2016-10-25T17:46:33.781Z",
              "type": "transaction.created",
              "data": {
                  "id": "AfLZQYR2RLGRqBxDo4IKIQ",
                  "created": "2016-10-25T17:46:33.778Z",
                  "modified": "2016-10-25T17:46:33.778Z",
                  "account_id": "8IO47jzCEeOfvhLxg70sog",
                  "status": "PENDING",
                  "amount": 100,
                  "currency": "USD",
                  "auto_capture": true,
                  "amount_refunded": 0,
                  "authorization_code": "U2QF6A",
                  "type": "CHARGE",
                  "method": {
                      "name": "Some Customer",
                      "address1": "123 Main St",
                      "postal_code": "78730",
                      "type": "card",
                      "number": "************4242",
                      "fingerprint": "GunPelYVthifNV63LEw1",
                      "card_type": "VISA",
                      "exp_month": 10,
                      "exp_year": 2025,
                      "cvv": "***"
                  }
              }
          }
      ]
  }
  
Retrieve the next 5 Events starting from Oct 1, 2016 at 14:33:29.105 UTC
curl -X GET --user secret_key: 'https://api.affinipay.com/v1/events?page=1&page_size=5&start_date=2016-10-01T14:33:29.105Z'
Example response
{
      "page": 1,
      "page_size": 5,
      "total_entries": 136,
      "results": [
          {
              "id": "RsRwETpFSJ2L3lyuPaFO0Q",
              "type": "transaction.created",
              "created": "2016-10-25T18:08:22.199Z",
              "data": {
                  "id": "z2jUj9JyRNG_nIQZr9L_CA",
                  "created": "2016-10-25T18:08:22.148Z",
                  "modified": "2016-10-25T18:08:22.148Z",
                  "account_id": "TU0BOD2gEeOfvhLxg70sog",
                  "status": "PENDING",
                  "amount": 1256,
                  "currency": "USD",
                  "auto_capture": false,
                  "reference": "auth ref 1256",
                  "amount_refunded": 0,
                  "authorization_code": "ZXSKRB",
                  "type": "CHARGE",
                  "method": {
                      "name": "Some Customer",
                      "address1": "123 Main St",
                      "postal_code": "78730",
                      "type": "card",
                      "number": "************4242",
                      "fingerprint": "GunPelYVthifNV63LEw1",
                      "card_type": "VISA",
                      "exp_month": 10,
                      "exp_year": 2025,
                      "cvv": "***"
                  }
              }
          }, {
              "id": "h00xvpjLS6usI3_Uv1TMlw",
              "created": "2016-10-25T18:08:22.293Z",
              "type": "transaction.authorized",
              ...
          }, {
              "id": "WjqzlbTwSHqB0xYS1BznXw",
              "created": "2016-10-25T18:08:22.436Z",
              "type": "transaction.created",
              ...
          }, {
              "id": "3mLZet76SrOMg0Gs3QsTbA",
              "created": "2016-10-25T18:08:22.473Z",
              "type": "transaction.authorized",
              ...
          }, {
              "id": "0QkrSnlaRW2F6GdiUd8w0Q",
              "created": "2016-10-25T18:08:22.567Z",
              "type": "transaction.created",
              ...
          }
      ]
  }
  

Object Types

All request and response content in the AffiniPay Payment Gateway API use JSON representations for serialization to and from the server. The following sections detail the properties, data types, and constraints of each of the types present in the API.

  • Boolean - Boolean values are represented using the JSON literal values true and false
  • Date: - Date values (with no time component) are represented using the format yyyy-mm-dd
  • Timestamp: - All timestamps sent or received by the Gateway use the ISO-8601 format yyyy-MM-dd'T'HH:mm:ss.SSS'Z', including fractional milliseconds, relative to the UTC time zone. For example, the timestamp 2016-08-21T15:32:21.702Z represents an occurrence on August 21, 2016 at 3:32:21.702 PM UTC.

ach_account

A merchant eCheck account's parameters, used to interact with payment processors to move funds between the merchant's bank account and customer bank accounts.

ParameterTypeDescription
idStringThe ID of the entity (read-only)
createdTimestampDate/time the entity was created (read-only)
modifiedTimestampDate/time the entity was last modified (read-only)
messagesArray of StringsValidation or warning messages associated with an operation requested on this entity (read-only)
trust_accountBooleanWhether or not this is a trust account. If unknown, the property is not returned (read-only)
statusStringStatus of the bank account (read-only). Enumeration of:
  • ACTIVE - The bank account is currently active
  • INACTIVE - The bank account is no longer active
  • DELETED - The bank account has been marked deleted
nameStringDescriptive name for the account, for display purposes only
primaryBooleanWhether this account is the Merchant's primary eCheck account. Exactly one eCheck account must always be marked as primary. The primary account is used for bank transactions that do not specify an account ID.
routing_numberString9-digit routing number of the merchant's bank
account_numberStringMerchant's bank account number. The value may be 4-17 digits, with no punctuation or other characters.
account_typeStringThe type of the merchant bank account specified, either checking or savings . Enumeration of:
  • CHECKING
  • SAVINGS
bank_nameStringName of the bank associated with the given routing number. The Gateway will attempt to populate this value automatically based on the routing number provided. (Read-only)
required_payment_fieldsStringComma-delimited list of zero or more bank properties on an eCheck transaction that are required to be present. The following property names of bank may be included in the list contents:
  • name
  • address1
  • city
  • state
  • postal_code
  • country
  • email
  • phone
transaction_allowed_countriesStringComma-delimited list of zero or more 2-letter ISO 3166 country codes for which remote client IP addresses are accepted for eCheck transaction operations on this account. The country is determined by geographic IP lookup. Transaction operations include Charge, Void, Capture, and Refund . If no countries are defined, the Merchant's Tenant may define a default list of countries. (read-only)
currencyString3-letter ISO currency code identifying the currency used for the account.

bank

Provides details for a customer and bank account for use in payment methods.

ParameterTypeDescription
idStringThe ID of the entity (read-only)
createdTimestampDate/time the entity was created (read-only)
modifiedTimestampDate/time the entity was last modified (read-only)
typeStringThe type of the payment method. For bank details, this is always bank.
token_idStringID of a one-time payment token from which to create the Bank (optional)
routing_numberString9-digit routing number of the customer's bank
account_numberStringCustomer's bank account number. The value may be 4-17 digits, with no punctuation or other characters.
account_typeStringThe type of the customer bank account specified, either checking or savings. Enumeration of:
  • CHECKING
  • SAVINGS
bank_nameStringName of the bank associated with the given routing number. The Gateway will attempt to populate this value automatically based on the routing number provided. (Read-only)
fingerprintStringA unique fingerprint for the bank routing and account number used. This fingerprint may be used to find other transactions with the merchant that used the same customer bank account. (Read-only)
account_holder_typeStringThe type of account holder, either individual or business (default is business)
nameStringBusiness name (required for business account_holder_type, ignored for individual account_holder_type)
given_nameStringThe first name of the account holder. Must be 2 or more letters. (required for eCheck user with individual account_holder_type, ignored for business account_holder_type)
surnameStringThe last name of the account holder. Must be 2 or more letters. (required for eCheck user with individual account_holder_type when using hosted fields, ignored for business account_holder_type)
address1StringCustomer address (optional)
address2StringAdditional address line (optional)
cityStringCustomer city (optional)
stateStringCustomer state. For US and Canada, this must be the 2-letter state or province code. (Optional)
postal_codeStringCustomer zip or postal code, consisting of 3 to 9 alphanumeric characters, as well as spaces and dashes. The total length of the postal code cannot exceed 10 characters. (Optional)
countryStringCustomer 2-letter ISO 3166 country code (optional)
emailStringCustomer email address (optional)
phoneStringCustomer phone number. No specific format is required, but the total length cannot exceed 22 characters. (Optional)
referenceStringA reference for the bank details, limited to 64 characters. This property is only used when creating a saved Bank instance, and can be used to retrieve the instance. For example, the reference can be set to a customer ID within the integrating merchant system, allowing all saved Banks for a given customer to be retrieved. (Optional)
descriptionStringDescription for the bank details, limited to 64 characters. Only used when creating a saved Bank instance. (Optional)

card

Provides details for a credit card and the card holder. For recurring payments, card instances can be saved and reused in future charges, refunds, and credits (if enabled) by specifying just the saved card's ID.

ParameterTypeDescription
idStringThe ID of the entity (read-only)
createdTimestampDate/time the entity was created (read-only)
modifiedTimestampDate/time the entity was last modified (read-only)
typeStringThe type of the payment method. For card details, this is always card.
token_idStringID of a one-time payment token from which to create the Card (optional)
numberStringThe credit card number (required unless track1 or track2 stripe data is provided, in which case the value is ignored)
fingerprintStringA unique fingerprint for the card number used. This fingerprint may be used to find other transactions with the merchant that used the same card. (read-only)
card_typeStringType of the credit card (optional). Enumeration of:
  • MASTERCARD
  • VISA
  • AMERICAN_EXPRESS
  • DISCOVER
  • DINERS_CLUB
  • JCB
  • UNKNOWN
exp_monthNumber, 1-12Card expiration month (required unless track1 or track2 stripe data is provided, in which case the value is ignored)
exp_yearNumber2 or 4-digit card expiration year (required unless track1 or track2 stripe data is provided, in which case the value is ignored)
cvvStringCard CVV (optional)
track1StringCard magnetic stripe track 1 data. The value should only include the contents of the stripe date between the track's start (% or ;) and end (?) sentinels.

For example, if the magnetic stripe reader returns %B4788250000028291^SOMEUSER^05121015432112345678?; 4788250000028291=05121015432112345678?, the track1 property would be set to B4788250000028291^SOME USER^05121015432112345678. (Optional).

track2StringCard magnetic stripe track 2 data. The value should only include the contents of the stripe date between the track's start (% or ;) and end (?) sentinels.

For example, if the magnetic stripe reader returns %B4788250000028291^SOMEUSER^05121015432112345678?; 4788250000028291=05121015432112345678?, the track1 property would be set to 4788250000028291=05121015432112345678. (Optional).

nameStringCard holder name (optional)
address1StringCard holder address (optional)
address2StringAdditional card holder address line (optional)
cityStringCard holder city (optional)
stateStringCard holder state. For US and Canada, this must be the 2-letter state or province code. (Optional)
postal_codeStringBilling zip or postal code, consisting of 3 to 9 alphanumeric characters, as well as spaces and dashes. The total length of the postal code cannot exceed 10 characters. (Optional)
countryStringCard holder 2-letter ISO 3166 country code (optional)
emailStringCustomer email address (optional)
phoneStringCustomer phone number. No specific format is required, but the total length cannot exceed 22 characters. (Optional)
referenceStringA reference for the card details, limited to 64 characters. This property is only used when creating a saved Card instance, and can be used to retrieve the instance. For example, the reference can be set to a customer ID within the integrating merchant system, allowing all saved Cards for a given customer to be retrieved. (Optional)
descriptionStringDescription for the card details, limited to 64 characters. Only used when creating a saved Card instance. (Optional)
statusStringWhether the card is available for use, according to our Account Updater service. An open status means the card is available; a closed status means the card is expired or has been closed.

charge

A credit card charge.

ParameterTypeDescription
idStringThe ID of the entity (read-only)
source_idStringThe URI that uniquely identifies a transaction in the caller's environment. Attempts to create another transaction (of any type) with the same source_id will result in an HTTP 409 with error code “resource_exists”. The recommended format is partnername:id. For example, if the partner's name is MyPartner, a source ID for a contact might be MyPartner:contact-12345. (optional, maximum length is 255 characters, write-only, must be unique to calling merchant)
createdTimestampDate/time the entity was created (read-only)
modifiedTimestampDate/time the entity was last modified (read-only)
messagesArray of StringsValidation or warning messages associated with an operation requested on this entity (read-only)
typeStringType of the transaction, used to differentiate Charges and Refunds in transaction search results. For Charges, the value is always CHARGE. (read-only)
account_idStringThe ID of the account to receive payment from the Charge (set at creation of the Charge, read-only thereafter)
statusStringStatus of the transaction (read-only). Enumeration of:
  • PENDING - The Gateway is awaiting confirmation from the processor of the transaction's creation.
  • AUTHORIZED - The transaction has been authorized.
  • COMPLETED - The Gateway has completed processing the transaction. Depending on the configuration and type of underlying Merchant or eCheck Account, settlement is either in process or complete.
  • VOIDED - The transaction has been voided.
  • FAILED - The transaction failed. Consult the failure code for details.
completion_timestampdatetimeThe date and time when the transaction was COMPLETED. If the status is not COMPLETED, this field is null. (read-only)
failure_codeStringFailure code indicating the reason a transaction's status was marked FAILED. The defined failure codes are the error message codes listed in Messages and Errors.
amountNumberThe amount to charge, in terms of the currency's smallest unit. For USD, this is the amount in cents. The maximum value is 10^14 - 1.
surcharge_amountNumberThe amount to be surcharged (in cents). This amount is equal to the surcharge fee or to the amount multiplied by the surcharge rate and is retrieved from the /bank-accounts/{bank_account_id}/surcharge endpoint. optional
currencyString3-letter ISO 4217 code representing the currency in which the amount is denominated (optional, defaults to USD)
methodPayment method or IDDetails of the card or bank to be charged. The contents of the payment details must be specified as a JSON hash or the String ID of a saved payment method or one-time token must be specified. When returned in a response, sensitive card details are either omitted (CVV) or masked (card number).
dataJSON hashA JSON hash containing any additional data to be included on the transaction. Storage charges may apply based on the amount of data saved.
auto_captureBooleanWhether the Charge will be automatically captured by the Gateway (if true) or the merchant must manually capture the transaction (if false, an "authorization-only" request to place a hold on funds). If not specified, the Gateway defaults to true and automatically captures the charge.
amount_refundedNumberThe total amount refunded from the authorized amount
authorization_codeStringThe authorization code provided by the payment processor following a successful authorization. This code is not guaranteed to be unique, although it is typically unique for the day of the transaction. (read-only)
cvv_resultStringCVV result from authorization of the Charge, if any (read-only). Enumeration of:
  • MATCHED - CVV matched
  • NOT_MATCHED - No match for CVV
  • ERROR - Unrecognized or unknown response
  • INVALID - Invalid response received from CVV check
  • NOT_PROCESSED - CVV could not be processed by issuer
  • NOT_PRESENT_ON_CARD - Issuer indicates no CVV present
  • UNAVAILABLE - CVV check is unavailable
  • NO_RESPONSE - No response from CVV check
avs_resultStringAVS result from authorization of the Charge, if any (read-only). Enumeration of:
  • ADDRESS - Address matches (AVS code "A")
  • ADDRESS_INTL - Address matches (international, AVS code "B")
  • NO_MATCH_INTL - No match on address or postal code (international, AVS code "C")
  • EXACT_MATCH_INTL - Exact match on address and postal code (international, AVS code "D")
  • AVS_ERROR_INELIGIBLE - AVS error or not eligible (AVS code "E")
  • EXACT_MATCH_UK - Exact match on address and postal code (UK-specific, AVS code "F")
  • NOT_SUPPORTED_INTL - AVS not supported by non-US issuer (AVS code "G")
  • UNAVAILABLE_INTL - AVS unavailable (international, AVS code "I")
  • ADDRESS_AND_POSTAL_CODE - Exact match of address and postal code (AVS code "M")
  • NO_MATCH - No match on address or postal code (AVS code "N")
  • POSTAL_CODE - Match on postal code (international, AVS code "P")
  • RETRY - AVS service not currently available from issuer (AVS code "R")
  • NOT_SUPPORTED - AVS not supported by US issuer (AVS code "S")
  • UNAVAILABLE - AVS unavailable (AVS code "U")
  • ZIP9 - Match on 9-digit US zip code (AVS code "W")
  • ADDRESS_AND_ZIP9 - Exact match of address and 9-digit US zip code (AVS code "X")
  • ADDRESS_AND_ZIP5 - Exact match of address and 5-digit US zip code (AVS code "Y")
  • ZIP5 - Match on 5-digit US zip code (AVS code "Z")
referenceStringAn optional reference provided by the Merchant when creating the Charge. This field is not used by the Gateway, but may be used by Merchant systems for correlation with invoices, etc. Maximum length is 128 characters.
capture_referenceStringAn optional reference provided by the Merchant when manually capturing the Charge. Note that this property may only be set for transactions with auto_capture set to false. Maximum length is 128 characters.
void_referenceStringAn optional reference provided by the Merchant when voiding the transaction. Maximum length is 128 characters.
recurring_charge_idStringThe ID of the RecurringCharge instance if the transaction was performed in the context of a recurring payment (read-only)
recurring_charge_ occurrence_idStringThe ID of the associated occurrence of the recurring payment, if any. This property is only set if recurring_charge_id is defined. (Read-only)
refundsArray of refundsSubsequent refunds applied to the Charge (read-only)

credit

A Credit returns funds to the customer card or bank provided in the payment method, without requiring a parent Charge.

ParameterTypeDescription
idStringThe ID of the entity. (read-only)
source_idStringA URI that uniquely identifies the transaction in the caller's environment. Attempts to create another transaction (of any type) with the same source_id will result in an HTTP 409 with error code “resource_exists”. The recommended format is partnername:id. For example, if the partner's name is MyPartner, a source ID for a contact might be MyPartner:contact-12345. (optional, maximum length is 255 characters, write-only, must be unique to calling merchant)
createdTimestampDate/time the entity was created. (read-only)
modifiedTimestampDate/time the entity was last modified. (read-only)
messagesArray of StringsValidation or warning messages associated with an operation requested on this entity. (read-only)
typeStringType of the transaction, used to differentiate Charges, Refunds, and Credits in transaction search results. For Credits, the value is always CREDIT. (read-only)
account_idStringThe ID of the account to receive payment from the Charge. (set at creation of the Charge, read-only thereafter)
statusStringStatus of the credit (read-only). Enumeration of:
  • PENDING - The Gateway is awaiting confirmation from the processor of the transaction's creation.
  • AUTHORIZED - The transaction has been authorized.
  • COMPLETED - The Gateway has completed processing the transaction. Depending on the configuration and type of underlying Merchant or eCheck Account, settlement is either in process or complete.
  • VOIDED - The transaction has been voided.
  • FAILED - The transaction failed. Consult the failure code for details.
completion_timestampdatetimeThe date and time when the transaction was COMPLETED. If the status is not COMPLETED, this field is null. (read-only)
failure_codeStringFailure code indicating the reason a credit's status was marked FAILED. The defined failure codes are the error message codes listed in Messages and Errors.
amountNumberThe amount to credit, in terms of the currency's smallest unit. For USD, this is the amount in cents. The maximum value is 10^14 - 1.
currencyString3-letter ISO 4217 code representing the currency in which the amount is denominated. (optional, defaults to USD)
auto_captureBooleanWhether or not the Credit will be automatically captured by the Gateway. At present, this value is always true. (Read-only)
methodPayment method or IDDetails of the card or bank to which funds are transferred. The contents of the payment details must be specified as a JSON hash or the String ID of a PaymentMethod, saved card, saved bank, or one-time token must be specified. When returned in a response, sensitive card details are either omitted (CVV) or masked (card number).
dataJSON hashA JSON hash containing any additional data to be included on the credit. Storage charges may apply based on the amount of data saved.
auto_captureBooleanWhether the Credit will be automatically captured by the Gateway. At present, this is always true.
referenceStringAn optional reference provided by the Merchant when creating the credit. This field is not used by the Gateway, but may be used by Merchant systems for correlation with invoices, etc. Maximum length is 128 characters.
void_referenceStringAn optional reference provided by the Merchant when canceling the credit. Maximum length is 128 characters.

event

An Event records the occurrence of a change in the Gateway system's state. The content of the event, available via the data property, is dictated by the type of the event.

ParameterTypeDescription
idStringThe ID of the entity (read-only)
createdTimestampDate/time the entity was created (read-only)
typeStringThe type of the event (read-only)
dataJSON hashThe content of the event (read-only)

loan

A loan.

ParameterTypeDescription
idStringThe ID of the entity (read-only)
createdTimestampDate/time the entity was created (read-only)
modifiedTimestampDate/time the entity was last modified (read-only)
givenNameStringThe first name of the loanee. Must be 2-40 characters. (read-only)
surnameStringThe last name of the loanee. Must be less than 64 characters. (read-only)
address1StringLoanee address. Must be less than 64 characters. (read-only)
address2StringAdditional address line. Must be less than 64 characters. (read-only)
cityStringLoanee city. Must be less than 64 characters. (read-only)
stateStringLoanee state. Must be less than 64 characters. (read-only)
postalCodeStringLoanee zip or postal code. (read-only)
countryStringLoanee 2-letter ISO 3166 country code. (read-only)
emailStringLoanee email address. Must be less than 254 characters. (read-only)
phoneStringLoanee phone number. Must be less than 22 characters. (read-only)

merchant

A business which processes payments using associated merchant and eCheck accounts.

ParameterTypeDescription
idStringThe ID of the entity (read-only)
createdTimestampDate/time the entity was created (read-only)
modifiedTimestampDate/time the entity was last modified (read-only)
messagesArray of StringsValidation or warning messages associated with an operation requested on this entity (read-only)
nameStringName of the Merchant
public_keyStringPublic identity of the Merchant, used to initialize hosted fields for payment form integration
contact_nameStringName of the contact at the Merchant
contact_emailStringEmail address used to contact the Merchant
contact_phoneStringPhone number used to contact the Merchant, in E-164 format. Leading '+' is optional.
address1StringMailing address of the Merchant
address2StringAdditional address field (optional)
cityStringCity in which the Merchant is located
stateStringState or province. For US and Canada, this must be the 2-letter state or province code in which the Merchant is located.
postal_codeStringMerchant zip or postal code, consisting of 3 to 9 alphanumeric characters, as well as spaces and dashes. The total length of the postal code cannot exceed 10 characters.
countryString2-letter ISO 3166 country code in which the Merchant's business is located
timezoneStringTime zone ID associated with the Merchant (e.g., "America/New_York") used for settlement
merchant_accountsArray of merchant_accountThe merchant's credit Accounts
ach_accountsArray of ach_accountThe merchant's bank accounts for eCheck transactions
api_allowed_ip_address_rangesStringComma-delimited list of zero or more CIDR-notation IP address ranges from which the Merchant's API requests are allowed. Requests made by the Merchant from IPs outside the defined ranges are rejected. If no address ranges are defined, authenticated requests are accepted from any IP.
live_events_urlsStringComma-delimited list of URLs to which merchant live-mode events are POSTed. Note that while no sensitive payment information is ever sent within event content, personally identifiable information such as customer names and addresses is contained within events. For this reason, event URLs should always use the HTTPS scheme. The length of the value cannot exceed 1024 characters.
test_events_urlsStringComma-delimited list of URLs to which merchant test-mode events are POSTed. Note that while no sensitive payment information is ever sent within event content, personally identifiable information such as customer names and addresses is contained within events. For this reason, event URLs should always use the HTTPS scheme. The length of the value cannot exceed 1024 characters.

merchant_account

A merchant bank account's parameters, used to interact with payment processors to move funds between the merchant's account and credit card accounts.

ParameterTypeDescription
idStringThe ID of the entity (read-only)
createdTimestampDate/time the entity was created (read-only)
modifiedTimestampDate/time the entity was last modified (read-only)
messagesArray of StringsValidation or warning messages associated with an operation requested on this entity (read-only)
trust_accountBooleanWhether or not this is a trust account. If unknown, the property is not returned (read-only).
statusStringStatus of the Account (read-only). Enumeration of:
  • ACTIVE - The account is currently active.
  • INACTIVE - The account is no longer active.
  • DELETED - The account has been marked deleted.
nameStringDescriptive name for the account, for display purposes only
primaryBooleanWhether this Account is the Merchant's primary account. Exactly one Account must always be marked as primary. The primary Account is used for Charges that do not specify an account ID.
currencyString3-letter ISO currency code identifying the currency used by the Merchant
accepted_card_typesStringComma-delimited list of zero or more card types accepted by the merchant. Transactions are rejected if a card number is provided which does not map to an accepted card type. Supported values are any card, as well as the special type * which indicates any card type is accepted.
cvv_policyStringThe CVV matching policy applied to non-swiped Charges made through the Account. Enumeration of:
  • DISABLED - CVV is not required.
  • OPTIONAL - CVV is not required, but if CVV data is present on the transaction, CVV checks are performed on the payment processor. Matching requirements are the same as REQUIRE_MATCH_LENIENT.
  • REQUIRE_MATCH_LENIENT - A CVV match is required, but transactions are permitted if CVV checks are not available on the payment processor or not applicable to the card.
  • REQUIRE_MATCH_STRICT - A CVV match is required. Transactions are rejected if CVV checks are not available on the payment processor or not applicable to the card.
avs_policyStringThe address verification policy applied to non-swiped Charges made through the Account. Enumeration of:
  • DISABLED - No AVS check is performed and neither address nor postal code is required.
  • SUBMIT_IGNORE_RESULT - An AVS check is performed on the address and postal code data, if available, and the result is stored on the Charge; however no action is taken based on the result (i.e., transactions are never rejected as a result of the AVS result). The calling application is responsible for voiding the transaction, if desired, based on the AVS result returned.
  • ADDR_OR_POSTAL_CODE_LENIENT - A match of the address or postal code is required. Transactions are permitted if AVS checks are not available on the payment processor or not applicable to the card.
  • ADDR_OR_POSTAL_CODE_STRICT - A match of the address or postal code is required. Transactions are rejected if AVS checks are not available on the payment processor or not applicable to the card.
  • ADDR_STRICT - An exact match of the address is required.
  • POSTAL_CODE_STRICT - An exact match of the postal code is required.
  • EXACT_ADDR_AND_POSTAL_CODE_LENIENT - An exact match of both the address and postal code is required. Transactions are permitted if AVS checks are not available on the payment processor or not applicable to the card.
  • EXACT_ADDR_AND_POSTAL_CODE_STRICT - An exact match of both the address and postal code is required. Transactions are rejected if AVS checks are not available on the payment processor or not applicable to the card.
ignore_avs_failure_if_cvv_matchBooleanWhether an AVS failure on a non-swiped Charge should be ignored provided the CVV match was successful. Only applicable if cvv_policy is not DISABLED.
required_payment_fieldsStringComma-delimited list of zero or more card field properties that are required to be present on non-swiped card details presented for Charges, Refunds and payment token generation. Card number, expiration month, and expiration year are always required for credit card payments. The following property names of cardmay be included in the list contents:
  • card_type
  • cvv
  • name
  • address1
  • city
  • state
  • postal_code
  • country
  • email
  • phone
swipe_cvv_policyStringThe CVV matching policy applied to retail swiped Charges made through the account. Available property values are identical to cvv_policy.
swipe_avs_policyStringThe AVS matching policy applied to retail swiped Charges made through the account. Available property values are identical to avs_policy.
swipe_ignore_avs_failure_if_cvv_matchBooleanWhether an AVS failure on a swiped Charge should be ignored provided the CVV match was successful. Only applicable if swipe_cvv_policy is not DISABLED.
swipe_required_payment_fieldsStringComma-delimited list of zero or more card field properties that are required to be present on swiped card details presented for Charges, Refunds and Payment Token generation. The set of supported values is identical to required_payment_fields.
transaction_allowed_countriesStringComma-delimited list of zero or more 2-letter ISO 3166 country codes for which remote client IP addresses are accepted for transaction operations on this account. The country is determined by geographic IP lookup. Transaction operations includeCharge, Void, Capture and Refund . If no countries are defined, the Merchant's Tenant may define a default list of countries.

recurring_charge

A recurring charge that automatically attempts to collect payment on a defined schedule.

ParameterTypeDescription
idStringThe ID of the entity (read-only)
source_idStringThe URI that uniquely identifies a transaction in the caller's environment. Attempts to create another transaction (of any type) with the same source_id will result in an HTTP 409 with error code “resource_exists”. The recommended format is partnername:id. For example, if the partner's name is MyPartner, a source ID for a contact might be MyPartner:contact-12345.(optional, maximum length is 255 characters, write-only, must be unique to calling merchant)
createdTimestampDate/time the entity was created (read-only)
modifiedTimestampDate/time the entity was last modified (read-only)
messagesArray of StringsValidation or warning messages associated with an operation requested on this entity (read-only)
statusStringStatus of the recurring charge (read-only). Enumeration of:
  • ACTIVE - The recurring charge has future scheduled payments to collect.
  • COMPLETED - Collection has been attempted on all scheduled payments for the recurring charge.
  • DELETED - The recurring charge has been deleted.
status_reasonStringReason code indicating why the recurring charge transitioned to the current status (read-only). Enumeration of:
  • schedule_complete - Recurring charge completed normally, having attempted all scheduled payments.
  • user_canceled - The Merchant canceled the recurring charge.
account_idStringThe ID of the account to receive payment from the recurring charge (set at creation of the recurring charge, read-only thereafter)
methodPayment method or IDDetails of the card or bank to be charged. The contents of the payment details must be specified as a JSON hash or the string ID of a saved payment method or one-time token must be specified. When returned in a response, sensitive card details are either omitted (CVV) or masked (card number).
scheduleScheduleThe schedule indicating when payments are due. Upon creation or update of a recurring charge, the Gateway calculates the next payment using the given schedule along with the configured start date and current date. For start dates occurring before the current date, the next payment is defined as the next eligible date (based on the schedule) on or after the current date.
descriptionStringDescription for the recurring charge (optional)
amountNumberThe amount to charge on each scheduled payment, in terms of the currency's smallest unit. For USD, this is the amount in cents. The maximum value is 10^14 - 1.
currencyString3-letter ISO 4217 code representing the currency in which the amount is denominated (optional, defaults to USD)
referenceStringAn optional reference to be set on each Charge created to collect a scheduled payment associated with this recurring charge (optional)
max_occurrencesNumberThe maximum number of scheduled payments that will be attempted before the recurring charge is automatically marked completed. Note that maximum occurrences tracks scheduled payments, and not actual transactions created to collect on those scheduled payments.

For example, a Charge associated with an occurrence may initially fail if the credit card associated with the recurring charge is declined or expired; however, after the payment details are updated, a subsequent Charge associated with the same occurrence may succeed. In this scenario, however, only a single occurrence is counted towards the max_occurrences limit.

max_amountNumberThe maximum amount the recurring charge will attempt to collect before the recurring charge is automatically marked completed. This value must be greater than or equal to amount. The final occurrence of a recurring charge will be the lesser of amount and the remainder of max_amount less total_amount.

For example, a recurring charge with a scheduled amount of $100 and a maximum amount of $150 will result in an initial occurrence for $100 followed by a final occurrence of $50. Note that max_amount, just like max_occurrences, tracks scheduled payments, and not actual transactions created to collect on those scheduled payments.

total_occurrencesNumberThe total number of occurrences for this recurring charge for which the Gateway has attempted to collect payment. This value does not include the next pending occurrence, if any. (Read-only)
total_amountNumberThe total amount for which the Gateway has attempted to collect payment for this recurring charge. This value does not include the amount for the next pending occurrence, if any. (Read-only)
next_paymentDateThe date the Gateway will attempt to collect the next payment, if any scheduled payments remain.
dataJSON hashA JSON hash containing any additional data to be included on each charge created to collect a scheduled payment. Storage charges may apply based on the amount of data saved.
occurrencesArray of recurring_charge_occurrencesThe recurring charge's occurrences, in order of increasing payment date. Occurrences are only returned following creation as a convenience to provide initial occurrence information(read-only)

recurring_charge_occurrence

An occurrence of a recurring charge. Occurrences track individual scheduled payments as defined by the schedule of the owning recurring_charge.

ParameterTypeDescription
idStringThe ID of the entity (read-only)
source_idStringThe URI that uniquely identifies a transaction in the caller's environment. Attempts to create another transaction (of any type) with the same source_id will result in an HTTP 409 with error code “resource_exists”. The recommended format is partnername:id. For example, if the partner's name is MyPartner, a source ID for a contact might be MyPartner:contact-12345. (optional, maximum length is 255 characters, write-only, must be unique to calling merchant)
createdTimestampDate/time the entity was created (read-only)
modifiedTimestampDate/time the entity was last modified (read-only)
recurring_charge_idStringID of the owning recurring charge (read-only)
amountNumberThe amount, in terms of the base unit of the owning recurring charge account's currency, to be collected by this occurrence (read-only)
statusStringThe status of the occurrence (read-only). Enumeration of:
  • PENDING - No attempt has yet been made to collect the payment for this occurrence. This is the initial state of all occurrences.
  • PAYING - The Gateway is currently authorizing a Charge to collect payment for this occurrence.
  • PAID - Payment was collected successfully for the occurrence.
  • IGNORED - No further attempts will be made to collect payment for this occurrence.
  • FAILED - The attempt to collect payment for this occurrence failed. The Merchant may manually attempt to collect the payment (for example, after waiting for available funds from the client or updating the recurring charge with new payment details) or mark the occurrence as ignored.
due_dateDateThe date the Gateway will attempt to collect payment for the occurrence (read-only)
attemptsNumberThe number of attempts made to collect payment on this occurrence (read-only)
last_attemptTimestampThe last time an attempt was made to collect payment for this occurrence (read-only)
transactionsArray of chargesThe transactions which have attempted to collect payment for this occurrence, in order of increasing creation timestamp (read-only)

recurring_charge_projection

A projection of the occurrences for a recurring charge for a defined schedule.

ParameterTypeDescription
amountNumberThe amount to charge on each scheduled payment, in terms of the currency's smallest unit. For USD, this is the amount in cents. The minimum value is 1. The maximum value is 10^14 - 1.
max_occurrencesNumberThe maximum number of scheduled payments that will be attempted before the recurring charge is automatically marked completed. Note that maximum occurrences tracks scheduled payments, and not actual transactions created to collect on those scheduled payments.

For example, a Charge associated with an occurrence may initially fail if the credit card associated with the recurring charge is declined or expired; however, after the payment details are updated, a subsequent Charge associated with the same occurrence may succeed. In this scenario, however, only a single occurrence is counted towards the max_occurrences limit. The minimum value is 1 (or null for unlimited).

max_amountNumberThe maximum amount the recurring charge will attempt to collect before the recurring charge is automatically marked completed. This value must be greater than or equal to amount. The final occurrence of a recurring charge will be the lesser of amount and the remainder of max_amount less total_amount.

For example, a recurring charge with a scheduled amount of $100 and a maximum amount of $150 will result in an initial occurrence for $100 followed by a final occurrence of $50. Note that max_amount, just like max_occurrences, tracks scheduled payments, and not actual transactions created to collect on those scheduled payments. The minimum value is 1 (or null for unlimited).

total_amountNumberThe total amount for which the Gateway has attempted to collect payment for this recurring charge. This value does not include the amount for the next pending occurrence, if any. The default is 0.
total_occurrencesNumberThe total number of occurrences for this recurring charge for which the Gateway has attempted to collect payment. This value does not include the next pending occurrence, if any.
remaining_occurrencesNumberThe total number of occurrences remaining for this recurring charge projection. This can be null if the schedule is boundless.
remaining_amountNumberThe total amount remaining for this recurring charge projection. This can be null if the schedule is boundless.
scheduleScheduleThe schedule indicating when payments are due. Upon creation or update of a recurring charge, the Gateway calculates the next payment using the given schedule along with the configured start date and current date. For start dates occurring before the current date, the next payment is defined as the next eligible date (based on the schedule) on or after the current date.
next_paymentDateThe date the Gateway will attempt to collect the next payment, if any scheduled payments remain.
occurrencesArrayThe recurring_charge_projection_occurrences, in order of increasing payment date. Occurrences are only returned following creation as a convenience to provide initial occurrence information(read-only)

recurring_charge_projection_occurrence

An occurrence of a recurring charge projection. Occurrences track individual scheduled payment projections as defined by the schedule of the owning recurring_charge_projection.

ParameterTypeDescription
amountNumberThe amount, in terms of the base unit of the owning recurring charge account's currency, to be collected by this occurrence. (read-only)
due_dateDateThe date the Gateway will attempt to collect payment for the occurrence. (read-only)

refund

A refund applied to an existing charge.

ParameterTypeDescription
idStringThe ID of the entity (read-only)
source_idStringThe URI that uniquely identifies a transaction in the caller's environment. Attempts to create another transaction (of any type) with the same source_id will result in an HTTP 409 with error code “resource_exists”. The recommended format is partnername:id. For example, if the partner's name is MyPartner, a source ID for a contact might be MyPartner:contact-12345. (optional, maximum length is 255 characters, write-only, must be unique to calling merchant)
createdTimestampDate/time the entity was created (read-only)
modifiedTimestampDate/time the entity was last modified (read-only)
messagesArray of StringsValidation or warning messages associated with an operation requested on this entity (read-only)
typeStringType of the transaction, used to differentiate Charges and Refunds in transaction search results. For Refunds, the value is always REFUND. (read-only)
account_idStringThe ID of the account to provide payment for the Refund (set at creation of the Refund, read-only thereafter)
statusStringStatus of the refund (read-only). Enumeration of:
  • PENDING - The Gateway is awaiting confirmation from the processor of the transaction's creation.
  • AUTHORIZED - The transaction has been authorized.
  • COMPLETED - The Gateway has completed processing the transaction. Depending on the configuration and type of underlying Merchant or eCheck Account, settlement is either in process or complete.
  • VOIDED - The transaction has been voided.
  • FAILED - The transaction failed. Consult the failure code for details.
completion_timestampdatetimeThe date and time when the transaction was COMPLETED. If the status is not COMPLETED, this field is null. (read-only)
failure_codeStringFailure code indicating the reason a transaction's status was marked FAILED. The defined failure codes are the error message codes listed in Messages and Errors.
amountNumberThe amount to refund, in terms of the currency's smallest unit. For USD, this is the amount in cents.
currencyString3-letter ISO 4217 code representing the currency in which the amount is denominated (optional, defaults to USD)
charge_idStringID of the charge to which the Refund was applied (read-only)
auto_captureBooleanWhether the transaction is automatically captured by the Gateway. For Refunds, this value is always true. (Read-only)
methodPayment method or IDDetails of the card or bank to be refunded. This should only be specified if a payment method different from the original should be refunded. Note that refunding to a non-originating payment method may not be permitted by the merchant's tenant. When returned in a response, sensitive card details are either omitted (CVV) or masked (card number).
referenceStringAn optional comment to be associated with the creation of the Refund. Maximum length is 128 characters.
dataJSON hashA JSON hash containing any additional data to be included on the transaction. Storage charges may apply based on the amount of data saved.

schedule

A schedule defining the occurrence of events, such as recurring charge payments.

ParameterTypeDescription
interval_unitStringThe interval unit of the schedule. Enumeration of:
  • DAY - Scheduled payments are performed every n days, based on the interval_delay.
  • WEEK - Scheduled payments are performed every n weeks, based on the interval_delay.
  • MONTH - Scheduled payments are performed every n months, based on the interval_delay.
interval_delayNumberThe frequency with which the schedule is executed, in terms of the interval_unit.

For example, if the interval unit is DAY, an interval delay of 1 means the schedule is executed every day; an interval delay of 2 means execution every other day; and an interval delay of 30 would mean the schedule is executed every 30 days.

startDateThe start date for the schedule such that the first occurrence may be executed on or after this date
endDateThe end date for the schedule such that the last occurrence is executed on or before this date (optional)
daysArray of StringSchedules for specific days of the week or month are created by defining the days property. This property can only be used with an interval_unit of WEEK or MONTH and an interval_delay of 1.

For weekly schedules, the values of this property are the ISO numeric days of the week: "1" for Monday, "2" for Tuesday, through "6" for Saturday and "7" for Sunday. For example, a schedule to be executed Mondays and Fridays would specify an array containing the values "1" and "5".

For monthly schedules, the values of this property are the days of the month, starting from "1", on which the schedule is executed. The keyword LAST can be used to indicate the last day of the month. For example, a schedule to be executed on the 15th and last days of each month would specify an array containing the values "15" and "LAST".

search_results

Results of a search performed on a resource type (such as charges).

ParameterTypeDescription
pageNumberThe logical "page" of the search results represented by this entity
page_sizeNumberThe maximum number of results requested per page
total_entriesNumberThe total number of search results available
resultsArray of resource types. The actual type varies with the API used.The page's search results

signature

A cardholder's signature.

ParameterTypeDescription
mime_typeStringThe only supported mime type value is "chargeio/jsignature". (required, maximum length is 64 characters)
datajSignatureThe signature itself. See https://willowsystems.github.io/jSignature/#/about/ for format information. (required, maximum length is 8192 characters)

token

A payment token is created in exchange for a customer's credit card and/or bank details, and can later be used in a charge or refund to provide payment information. Payment tokens are used to allow merchant systems to process payments on behalf of their customers without storing sensitive payment information on their own systems. Tokens are automatically deleted after use, and after 5 minutes if never used. Support for longer-term reusable payment mechanisms is available through PaymentMethod, saved bank, and saved card.

Payment tokens can be created with either credit card information (for credit transactions), or bank information (for eCheck payments). The token's type property determines how the data is used to create a payment method.

ParameterTypeDescription
idStringThe ID of the token, which can be passed in a future Charge or Refund request (read-only)
createdTimestampDate/time the entity was created (read-only)
modifiedTimestampDate/time the entity was last modified (read-only)
messagesArray of StringsValidation or warning messages associated with an operation requested on this entity (read-only)
typeStringType of the payment method (required for eCheck). Enumeration of:
  • bank
  • card
numberStringCustomer's credit card number (required for card)
card_typeStringType of the credit card (optional). Enumeration of:
  • MASTERCARD
  • VISA
  • AMERICAN_EXPRESS
  • DISCOVER
  • DINERS_CLUB
  • JCB
  • UNKNOWN
exp_monthNumber, 1-12Card expiration month (required for card)
exp_yearNumber2 or 4-digit card expiration year (required for card)
cvvStringCard CVV (required for card)
routing_numberString9-digit routing number of the customer's bank (required for eCheck)
account_numberStringCustomer's bank account number. The value may be 4-17 digits, with no punctuation or other characters. (required for eCheck)
account_typeStringThe type of the customer bank account specified, either checking or savings (required for eCheck). Enumeration of:
  • CHECKING
  • SAVINGS
account_holder_typeStringThe type of account holder, either individual or business (required for eCheck)
nameStringThe name of the account holder or business (required for eCheck with business account_holder_type, optional for card)
given_nameStringThe first name of the account holder. Must be 2 or more letters. (required for eCheck with individual account_holder_type, ignored for business account_holder_type, optional for card)
surnameStringThe last name of the account holder. Must be 2 or more letters. (optional for eCheck with individual account_holder_type, ignored for business account_holder_type, optional for card)
address1StringCustomer address (optional)
address2StringAdditional address line (optional)
cityStringCustomer city (optional)
stateStringCustomer state. For US and Canada, this must be the 2-letter state or province code. (optional)
postal_codeStringCustomer zip or postal code, consisting of 3 to 9 alphanumeric characters, as well as spaces and dashes. The total length of the postal code cannot exceed 10 characters. (required for all partners for card)
countryStringCustomer 2-letter ISO 3166 country code (optional)
emailStringCustomer email address (optional)
phoneStringCustomer phone number. No specific format is required, but the total length cannot exceed 22 characters. (Optional)
referenceStringAn external reference for the payment details, such as a customer ID. The length may not exceed 64 characters. (Optional)
descriptionStringDescription for the payment details, limited to 64 characters (optional)
form_dataJSON hash

A JSON hash containing any additional FORM parameters that were posted with the payment token. Each parameter is a key in the hash, and the value is either the String FORM value for the parameter, or an Array of Strings (if the key was present multiple times in the FORM POST).

The form data is provided to ease validation for integrating Merchant systems with more complicated payment forms. The payment form can contain arbitrary data beyond just the payment details, and all this data is included with the token. Following the exchange of the token for the card details, the integrating system can retrieve the token (along with all the additional form parameters) and perform server-side validation within the Merchant system before choosing whether to proceed with issuing the charge request to the Gateway.

Messages and Errors

The Gateway communicates information about the outcome of processing a request using the messages key in the returned JSON response. The messages value is an array of JSON entities, each containing a single message.

For example, a charge request may return failure information related to an invalid card number or missing required data.

Each message contains a code describing the specific problem. All of the codes are listed in the following sections. Each message also contains a level describing the severity of the message. Levels include:

  • info - Informational, does not impact the outcome of processing the request.
  • error - A failure occurred while processing the request, preventing it from completing successfully.

The facility attribute specifies the Gateway subsystem from which the error originated. Facilities include:

  • gateway - The default facility, indicating no specific subsystem within the Gateway.
  • payment_processor - The backend payment processing network.

An optional message may be returned in the message. This value provides a text description intended for human consumption.

Certain error codes include additional context data within the message. These additions are described in the documentation for the corresponding error code.

Failure due to invalid card number
{
      "messages": [
          {
              "code": "card_number_invalid",
              "level": "error",
              "message": "Card number is invalid",
              "facility": "gateway"
          }
      ],
      ...
  }
  
Failure due to missing required data:
{
      "messages": [
          {
              "context": "method.name",
              "code": "invalid_data",
              "sub_code": "not_blank",
              "level": "error",
              "message": "Name cannot be blank",
              "facility": "gateway"
          }, {
              "context": "method.address1",
              "code": "invalid_data",
              "sub_code": "not_blank",
              "level": "error",
              "message": "Street number cannot be blank",
              "facility": "gateway"
          }, {
              "context": "method.number",
              "code": "invalid_data",
              "sub_code": "invalid_length",
              "level": "error",
              "message": "Card number length is invalid",
              "facility": "gateway"
          }
      ],
      ...
  }
  

General Messages

The following message codes are common to the Gateway API and may be returned from most of the operations.

not_authorized

A not_authorized error is returned if an API is invoked with incorrect or missing credentials, or with credentials that do not permit access to the requested operation or resource.

Level
error
HTTP Status Code
401

Example

{
  "messages": [
      {
          "code": "not_authorized",
          "level": "error",
          "message": "Not authorized",
          "facility": "gateway"
      }
  ]
  }
  

not_authorized_country_denied

A not_authorized_country_denied error indicates an operation was attempted from an IP in a country not allowed by the policy in effect. This error is typically recorded on failed transactions, and is not returned directly in an API response for security reasons, to avoid providing additional context to a potential attacker.

Level
error
HTTP Status Code
401

malformed_request

A malformed_request error is returned if an API is invoked with request content that cannot be parsed as a JSON request on the server.

Level
error
HTTP Status Code
400

Example

{
      "messages": [
          {
              "code": "malformed_request",
              "level": "error",
              "message" : "Unable to process JSON content",
              "facility": "gateway"
          }
      ]
  }
  

invalid_request

The Gateway returns an invalid_request error if the request cannot be processed due to factors unrelated to the request's JSON content. Typical scenarios in which this error is returned include requesting an unsupported HTTP method for a REST URL (such as a POST to a URL that only supports GET) and using an unsupported HTTP Content-Type for a REST URL (such as "application/x-www-form-urlencoded" rather than "application/json").

Level
error
HTTP Status Code
400

Example

{
      "messages": [
          {
              "code": "invalid_request",
              "level": "error",
              "message" : "Invalid request",
              "facility": "gateway"
          }
      ]
  }
  

no_content

A no_content error is returned if an API is invoked that requires JSON request content to be provided (for example, a charge request), but no content was sent in the request.

Level
error
HTTP Status Code
422

Example

{
      "messages": [
          {
              "code": "no_content",
              "level": "error",
              "message": "No JSON content received",
              "facility": "gateway"
          }
      ]
  }
  

invalid_data

The Gateway returns invalid_data if the server is not able to parse the JSON request, the request is missing required keys, or the values of keys is invalid. If the failure is due to a specified key in the request, the message will indicate the problematic field in the context key. Nested properties are indicated using a '.'.

For example, the JSON request for a charge contains a "card" key with a nested "name". If the name is problematic, the context will contain card.name.

A description of the field's problem is provided in the sub_code key. Values for the sub_code include:

  • number_out_of_range - The value given is not within the required numeric range of the field.
  • invalid_length - The length of the value is outside the accepted range.
  • exceeds_maximum_value - The value exceeds the maximum allowed.
  • below_minimum_value - The value is less than the minimum allowed.
  • not_blank - An empty/blank value is not allowed.
  • not_null - A null value is not allowed.
  • invalid - The value of the field is invalid, but no specific reason is available.
Level
error
HTTP Status Code
422

Example

{
      "messages": [
          {
              "context": "card.name",
              "code": "invalid_data",
              "sub_code": "not_blank",
              "level": "error",
              "message": "may not be empty",
              "facility": "gateway"
          }, {
              "context": "`card`.postal_code",
              "code": "invalid_data",
              "sub_code": "not_blank",
              "level": "error",
              "message": "may not be empty",
              "facility": "gateway"
          }
      ]
  }
  

invalid_data_encryption

An invalid_data_encryption error is returned if an API is invoked that contains encrypted content but decryption could not be performed by the Gateway.

Level
error
HTTP Status Code
422

Example

{
      "messages": [
          {
              "code": "invalid_data_encryption",
              "level": "error",
              "message": "The value could not be decrypted",
              "facility": "gateway"
          }
      ]
  }
  

resource_not_found

A resource, such as a charge or merchant account, was specified in the request, but not found. If available, the type and identity of the resource is included in the context key, in the format "resource-type" [ "identity" ].

This message is also returned if an invalid URL is specified; in this case, no context is included in the response.

Level
error
HTTP Status Code
404

Example

{
      "messages": [
          {
              "context": "Account[wKgFeD0XFtWBPRxEVWcAmg]",
              "code": "resource_not_found",
              "level": "error",
              "message": "Requested resource not found",
              "facility": "gateway"
          }
      ]
  }
  

unavailable_for_current_status

An operation was performed on a REST entity that could not be completed due to the entity's current status.

Level
error
HTTP Status Code
422

Example

{
      "messages": [
          {
              "code": "unavailable_for_current_status",
              "level": "error",
              "message": "The current status of the entity does not allow the requested operation",
              "facility": "gateway"
          }
      ]
  }
  

no_account_specified

No merchant account was specified for a request that requires an account.

Level
error
HTTP Status Code
422

Example

{
      "messages": [
          {
              "code": "no_account_specified",
              "level": "error",
              "message": "An account ID must be specified",
              "facility": "gateway"
          }
      ]
  }
  

merchant_not_active

An operation was attempted as a merchant, but the merchant has been suspended or made inactive.

Level
error
HTTP Status Code
422

Example

{
      "messages": [
          {
              "code": "merchant_not_active",
              "level": "error",
              "message": "Merchant is not active",
              "facility": "gateway"
          }
      ]
  }
  

unavailable_for_merchant_status

An operation on a merchant was prohibited due to the status of the merchant.

Level
error
HTTP Status Code
422

Example

{
      "messages": [
          {
              "code": "unavailable_for_merchant_status",
              "level": "error",
              "message": "The operation cannot be completed due to the current merchant status",
              "facility": "gateway"
          }
      ]
  }
  

account_not_active

An operation was performed on a merchant account for which the status was not ACTIVE.

Level
error
HTTP Status Code
422

Example

{
      "messages": [
          {
              "code": "account_not_active",
              "level": "error",
              "message": "Account is not active",
              "facility": "gateway"
          }
      ]
  }
  

unavailable_for_merchant_mode

An operation was attempted in a merchant mode (LIVE or TEST, depending on the credentials provided) that was not permitted on the target resource. For example, attempting to perform a charge in LIVE mode against an account of type TEST.

Level
error
HTTP Status Code
422

Example

{
      "messages": [
          {
              "code": "unavailable_for_merchant_mode",
              "level": "error",
              "message": "Mode LIVE not supported for account of type TEST",
              "facility": "gateway"
          }
      ]
  }
  

unavailable_for_merchant_policy

An operation was attempted by a merchant that is prohibited by the merchant's policy; for example, an attempt to perform a credit when credit operations are not enabled for the target account.

Level
error
HTTP Status Code
422

Example

{
      "messages": [
          {
              "code": "unavailable_for_merchant_policy",
              "level": "error",
              "message": "The operation is unavailable due to the current merchant policy",
              "facility": "gateway"
          }
      ]
  }
  

no_payment_method

The Gateway returns a no_payment_method error code if a payment API is invoked without providing any payment details in the request content.

Level
error
HTTP Status Code
422

Example

{
      "messages": [
          {
              "code": "no_payment_method",
              "level": "error",
              "message": "No payment method was specified",
              "facility": "gateway"
          }
      ]
  }
  

no_account_for_payment_method

If a payment API is invoked providing a payment method (a bank or card) for which no supporting account is configured on the merchant, a no_account_for_payment_method error is returned. For example, a bank charge performed on a merchant with no eCheck account configured will raise this error.

Level
error
HTTP Status Code
422

Example

{
      "messages": [
          {
              "code": "no_account_for_payment_method",
              "level": "error",
              "message": "Merchant does not have an account that supports the requested payment method",
              "facility": "gateway"
          }
      ]
  }
  

incorrect_payment_type

A transaction was performed that supplied payment details that were not applicable for the underlying account.

Level
error
HTTP Status Code
422

Example

{
      "messages": [
          {
              "code": "incorrect_payment_type",
              "level": "error",
              "message": "Payment method type not supported by the target account",
              "facility": "gateway"
          }
      ]
  }
  

payment_method_expired

A payment operation was attempted with a payment object that has expired. This typically occurs if a saved card object is used after it has been marked expired due to the card expiration.

Level
error
HTTP Status Code
422

Example

{
      "messages": [
          {
              "code": "payment_method_expired",
              "level": "error",
              "message": "Payment method expired",
              "facility": "gateway"
          }
      ]
  }
  

search_failed

The Gateway was unable to execute a search request using the parameters provided.

Level
error
HTTP Status Code
422

Example

{
      "messages": [
          {
              "code": "search_failed",
              "level": "error",
              "message": "The search could not be processed as defined",
              "facility": "gateway"
          }
      ]
  }
  

server_error

The Gateway encountered an unexpected error processing the request.

Level
error
HTTP Status Code
500

Example

{
      "messages": [
          {
              "code": "server_error",
              "level": "error",
              "message": "An unexpected error occurred",
              "facility": "gateway"
          }
      ]
  }
  

version_conflict

An attempt was made to update a resource, but another party modified the same resource prior to commit, moving the version ahead.

Level
error
HTTP Status Code
409

Example

{
      "messages": [
          {
              "code": "version_conflict",
              "level": "error",
              "message": "Version conflict",
              "facility": "gateway"
          }
      ]
  }
  

Card Validation Messages

The following message codes are returned to indicate validation problems with submitted card details that prevent transactions from being processed.

card_number_invalid

A card_number_invalid error is returned if a card number is not valid, either due to the Luhn checksum of the number's digits not matching, or as a result of a payment processor indicating invalid status.

Level
error
HTTP Status Code
422

Example

{
      "messages": [
          {
              "code": "card_number_invalid",
              "level": "error",
              "facility": "gateway"
          }
      ]
  }
  

card_number_incorrect

A card_number_incorrect error is returned if the caller provides both a card number and card type (VISA, MASTERCARD, etc), but the card number is not valid for the specified type.

Level
error
HTTP Status Code
422
Example
{
      "messages": [
          {
              "code": "card_number_incorrect",
              "level": "error",
              "facility": "gateway"
          }
      ]
  }
  

card_expired

The Gateway returns a card_expired error if card details are provided corresponding to an expired card.

Level
error
HTTP Status Code
422

Example

{
      "messages": [
          {
              "code": "card_expired",
              "level": "error",
              "facility": "gateway"
          }
      ]
  }
  

card_cvv_incorrect

If the policy applied to a merchant account requires the provided card CVV to match, but the payment processor indicates no match was present, the Gateway returns a card_cvv_incorrect and rejects the request.

Level
error
HTTP Status Code
422

Example

{
      "messages": [
          {
              "code": "card_cvv_incorrect",
              "level": "error",
              "facility": "payment_processor"
          }
      ]
  }
  

card_avs_rejected

If the policy applied to a merchant account requires the provided card address and/or postal code to match, but the payment processor indicates no match was present, the Gateway returns a card_avs_rejected and rejects the request.

Level
error
HTTP Status Code
422

Example

{
      "messages": [
          {
              "code": "card_avs_rejected",
              "level": "error",
              "facility": "payment_processor"
          }
      ]
  }
  

Card Processing Messages

The following message codes are returned to indicate problems processing transactions submitted to the Gateway.

no_card_details_or_token_present

If neither card details nor a valid payment token are provided on a charge or credit request, the Gateway returns a no_card_details_or_token_present error and rejects the request.

Level
error
HTTP Status Code
422

Example

{
      "messages": [
          {
              "code": "no_card_details_or_token_present",
              "level": "error",
              "facility": "gateway"
          }
      ]
  }
  

not_valid_for_transaction_status

The Gateway returns a not_valid_for_transaction_status error code if the current state of a transaction does not permit a given request to be performed. For example, a charge cannot be voided once it is in a COMPLETED state.

Level
error
HTTP Status Code
422

Example

{
      "messages": [
          {
              "code": "not_valid_for_transaction_status",
              "level": "error",
              "facility": "gateway"
          }
      ]
  }
  

unavailable_due_to_capture_in_process

A unavailable_due_to_capture_in_process error is returned if an attempt is made to capture a transaction while other transactions associated with the same merchant account are already in the process of being captured.

Level
error
HTTP Status Code
422

Example

{
      "messages": [
          {
              "code": "unavailable_due_to_capture_in_process",
              "level": "error",
              "facility": "gateway"
          }
      ]
  }
  

exceeds_authorized_amount

The Gateway returns a exceeds_authorized_amount error code if a capture request is made specifying an amount greater than the amount that was originally authorized.

Level
error
HTTP Status Code
422

Example

{
      "messages": [
          {
              "code": "exceeds_authorized_amount",
              "level": "error",
              "facility": "gateway"
          }
      ]
  }
  

refund_exceeds_transaction

If a refund or credit is applied to a charge such that the amount to be refunded exceeds the remaining amount of the charge (having deducted all previous refunds and credits), the Gateway returns a refund_exceeds_transaction error code and rejects the request.

Level
error
HTTP Status Code
422

Example

{
      "messages": [
          {
              "code": "refund_exceeds_transaction",
              "level": "error",
              "facility": "gateway"
          }
      ]
  }
  

currency_mismatch

The Gateway returns a currency_mismatch error if the currency specified on a credit or refund (if present) does not match the currency of the target charge.

Level
error
HTTP Status Code
422

Example

{
      "messages": [
          {
              "code": "currency_mismatch",
              "level": "error",
              "facility": "gateway"
          }
      ]
  }
  

unsupported_currency

If a merchant account cannot accept the currency designated by the currency code given on an authorize or charge request, the Gateway returns a unsupported_currency error code and rejects the request.

Level
error
HTTP Status Code
422

Example

{
      "messages": [
          {
              "code": "unsupported_currency",
              "level": "error",
              "facility": "gateway"
          }
      ]
  }
  

card_declined

The Gateway returns a card_declined error when a card number is provided that matches a card in the Gateway's blacklist, or the payment processor returns a decline response.

Level
error
HTTP Status Code
422

Example

{
      "messages": [
          {
              "code": "card_declined",
              "level": "error",
              "facility": "payment_processor"
          }
      ]
  }
  

card_declined_processing_error

The Gateway returns a card_declined_processing_error error if the payment processor indicates a card has been declined due to a processing error.

Level
error
HTTP Status Code
422

Example

{
      "messages": [
          {
              "code": "card_declined_processing_error",
              "level": "error",
              "facility": "payment_processor"
          }
      ]
  }
  

card_declined_insufficient_funds

Attempts to create a charge using a card with insufficient funds available results in a card_declined_insufficient_funds being returned by the Gateway.

Level
error
HTTP Status Code
422

Example

{
      "messages": [
          {
              "code": "card_declined_insufficient_funds",
              "level": "error",
              "facility": "payment_processor"
          }
      ]
  }
  

card_declined_limit_exceeded

Example

If a payment processor indicates a card has reached a spending limit, the Gateway returns a card_declined_limit_exceeded error code to the caller and rejects the request.

Level
error
HTTP Status Code
422
Example
{
      "messages": [
          {
              "code": "card_declined_limit_exceeded",
              "level": "error",
              "facility": "payment_processor"
          }
      ]
  }
  

card_declined_refer_to_issuer

If a payment processor indicates a card was declined with a referral to the issuer, the Gateway returns a card_declined_refer_to_issuer error.

Level
error
HTTP Status Code
422

Example

{
      "messages": [
          {
              "code": "card_declined_refer_to_issuer",
              "level": "error",
              "facility": "payment_processor"
          }
      ]
  }
  

card_declined_hold

A payment processor that responds to an authorize or charge request with a "Hold" response (meaning the card has been reported stolen or fraudulently used, and should be physically held and reported to the issuer) will cause the Gateway to return a card_declined_hold error to the caller, allowing the caller to carry out the hold request.

Level
error
HTTP Status Code
422

Example

{
      "messages": [
          {
              "code": "card_declined_hold",
              "level": "error",
              "facility": "payment_processor"
          }
      ]
  }
  

card_declined_no_account

The Gateway returns a card_declined_no_account error if the payment processor does not find any account associated with a card number submitted in an authorize or charge request.

Level
error
HTTP Status Code
422

Example

{
      "messages": [
          {
              "code": "card_declined_no_account",
              "level": "error",
              "facility": "payment_processor"
          }
      ]
  }
  

card_type_not_accepted

The Gateway returns a card_type_not_accepted error if an unsupported card type (VISA, MASTERCARD, etc) is used in a charge or credit operation. The supported card types are based on the merchant account configuration with the issuing bank.

Level
error
HTTP Status Code
422

Example

{
    "messages": [
        {
            "code": "card_type_not_accepted",
            "level": "error",
            "facility": "payment_processor"
        }
    ]
 }
 

merchant_trans_max_amount_exceeded

If the maximum single-transaction amount defined on a merchant account would be exceeded by an authorize or charge request to that account, the Gateway rejects the request with a merchant_trans_max_amount_exceeded error.

Level
error
HTTP Status Code
422

Example

{
      "messages": [
          {
              "code": "merchant_trans_max_amount_exceeded",
              "level": "error",
              "facility": "gateway"
          }
      ]
  }
  

merchant_trans_daily_count_exceeded

If the daily maximum number of transactions defined on a merchant account would be exceeded by an authorize or charge request to that account, the Gateway rejects the request with a merchant_trans_daily_count_exceeded error.

Level
error
HTTP Status Code
422

Example

{
      "messages": [
          {
              "code": "merchant_trans_daily_count_exceeded",
              "level": "error",
              "facility": "gateway"
          }
      ]
  }
  

merchant_trans_daily_amount_exceeded

An authorize or charge request for which the amount, when combined with the total value of all transactions on the same account over the previous 24 hours, exceeds the maximum daily amount defined on the merchant account, is rejected with a merchant_trans_daily_amount_exceeded error.

Level
error
HTTP Status Code
422

Example

{
      "messages": [
          {
              "code": "merchant_trans_daily_amount_exceeded",
              "level": "error",
              "facility": "gateway"
          }
      ]
  }
  

merchant_trans_monthly_count_exceeded

If the monthly maximum number of transactions defined on a merchant account would be exceeded by an authorize or charge request to that account, the Gateway rejects the request with a merchant_trans_monthly_count_exceeded error.

Level
error
HTTP Status Code
422

Example

{
      "messages": [
          {
              "code": "merchant_trans_monthly_count_exceeded",
              "level": "error",
              "facility": "gateway"
          }
      ]
  }
  

merchant_trans_monthly_amount_exceeded

An authorize or charge request for which the amount, when combined with the total value of all transactions on the same account over the previous 30 days, exceeds the maximum monthly amount defined on the merchant account, is rejected with a merchant_trans_monthly_amount_exceeded error.

Level
error
HTTP Status Code
422

Example

{
      "messages": [
          {
              "code": "merchant_trans_monthly_amount_exceeded",
              "level": "error",
              "facility": "gateway"
          }
      ]
  }
  

card_processor_not_available

If the Gateway cannot communicate with the payment processor associated with a merchant account to carry out a request, a card_processor_not_available error is returned. This is typically a transient problem and can be retried at a later time. The ID of the failed transaction is returned in the entity_id property.

Level
error
HTTP Status Code
500

Example

{
      "messages": [
          {
              "code": "card_processor_not_available",
              "level": "error",
              "facility": "payment_processor",
              "entity_id": "jCEP6Mn3Q2Cg4nS3qqqDuw"
          }
      ]
  }
  

card_processing_error

If a payment processor reports a failure to process a request on behalf of the Gateway, a card_processing_error error is returned to the caller. Unlike failures to communicate with the processor, retrying the operation may not resolve the issue. The ID of the failed transaction is returned in the entity_id property.

Level
error
HTTP Status Code
500

Example

{
      "messages": [
          {
              "code": "card_processing_error",
              "level": "error",
              "facility": "payment_processor",
              "entity_id": "jCEP6Mn3Q2Cg4nS3qqqDuw"
          }
      ]
  }
  

settlement_failed

A transaction that cannot be settled is marked as failed, and its failure code is set to settlement_failed.

Level
error
HTTP Status Code
500

Example

{
      "messages": [
          {
              "code": "settlement_failed",
              "level": "error",
              "facility": "payment_processor"
          }
      ]
  }
  

eCheck Processing Messages

The following message codes are returned to indicate problems processing eCheck transactions submitted to the Gateway.

no_bank_details_or_token_present

If neither bank details nor a valid payment token are provided on an eCheck transfer request, the Gateway returns a no_bank_details_or_token_present error and rejects the request.

Level
error
HTTP Status Code
422

Example

{
      "messages": [
          {
              "code": "no_bank_details_or_token_present",
              "level": "error",
              "facility": "payment_processor"
          }
      ]
  }
  

ach_declined

If the eCheck processor declines the transaction the Gateway returns a ach_declined error and rejects the request.

Level
error
HTTP Status Code
422

Example

{
      "messages": [
          {
              "code": "ach_declined",
              "level": "error",
              "facility": "payment_processor"
          }
      ]
  }

ach_declined_hold

An eCheck request that is declined due to the processor indicating possible fraudulent use of the bank account or account details returns a ach_declined_hold error code.

Level
error
HTTP Status Code
422

Example

{
      "messages": [
          {
              "code": "ach_declined_hold",
              "level": "error",
              "facility": "payment_processor"
          }
      ]
  }
  

ach_declined_duplicate

An eCheck processor may reject a transaction if it appears to be a duplicate of a previous transaction. In this case, the Gateway returns an ach_declined_duplicate error code to the caller.

Level
error
HTTP Status Code
422

Example

{
      "messages": [
          {
              "code": "ach_declined_duplicate",
              "level": "error",
              "facility": "payment_processor"
          }
      ]
  }
  

ach_invalid_account_number

An account number provided for an eCheck transaction that is structurally invalid (for example, due to a checksum mismatch) results in the Gateway returning an ach_invalid_account_number error code.

Level
error
HTTP Status Code
422

Example

{
      "messages": [
          {
              "code": "ach_invalid_account_number",
              "level": "error",
              "facility": "payment_processor"
          }
      ]
  }
  

ach_invalid_routing_number

The Gateway returns an ach_invalid_routing_number error code when an invalid routing number is provided for an eCheck transaction.

Level
error
HTTP Status Code
422

Example

{
      "messages": [
          {
              "code": "ach_invalid_routing_number",
              "level": "error",
              "facility": "payment_processor"
          }
      ]
  }
  

ach_insufficient_funds

When the balance of an account providing funds for an eCheck transaction is insufficient to cover the value of the transaction, the Gateway returns an ach_insufficient_funds error code.

Level
error
HTTP Status Code
422

Example

{
      "messages": [
          {
              "code": "ach_insufficient_funds",
              "level": "error",
              "facility": "payment_processor"
          }
      ]
  }
  

ach_account_not_found

If either bank account involved in an eCheck transaction cannot be found during execution of the transaction, the Gateway returns an ach_account_not_found error code.

Level
error
HTTP Status Code
422

Example

{
      "messages": [
          {
              "code": "ach_account_not_found",
              "level": "error",
              "facility": "payment_processor"
          }
      ]
  }
  

ach_account_closed

The Gateway returns an ach_account_closed error code when an account involved in an eCheck transaction is reported as closed.

Level
error
HTTP Status Code
422

Example

{
      "messages": [
          {
              "code": "ach_account_closed",
              "level": "error",
              "facility": "payment_processor"
          }
      ]
  }
  

ach_account_frozen

An attempt to perform an eCheck transaction against an account that has been frozen due to legal proceedings or other reasons is marked failed and returns an ach_account_frozen error code.

Level
error
HTTP Status Code
422

Example

{
      "messages": [
          {
              "code": "ach_account_frozen",
              "level": "error",
              "facility": "payment_processor"
          }
      ]
  }
  

ach_not_authorized

An account holder may notify his or her bank that a given eCheck transaction was not authorized. The Gateway receives this notification from the eCheck processor and marks the transaction failed with an ach_not_authorized error code.

Level
error
HTTP Status Code
N/A

ach_authorization_revoked

For a specific eCheck transaction, an account holder may revoke authorization for a previously authorized transfer. When the Gateway receives this notification, the transaction is marked failed with an ach_authorization_revoked error code.

Level
error
HTTP Status Code
N/A

ach_payment_stopped

An eCheck transaction for which payment has been stopped by the account holder is marked as failed with an ach_payment_stopped error code.

Level
error
HTTP Status Code
N/A

ach_payment_refused

An account holder may refuse an eCheck transaction due to an error in the amount or other issues with the transaction. In this case, the Gateway will mark the transaction failed with an ach_payment_refused error code.

Level
error
HTTP Status Code
N/A

ach_limit_exceeded

The Gateway returns an ach_limit_exceeded error code if the eCheck processor reports a transaction has exceeded the authorized limit.

Level
error
HTTP Status Code
422

Example

{
      "messages": [
          {
              "code": "ach_limit_exceeded",
              "level": "error",
              "facility": "payment_processor"
          }
      ]
  }
  

ach_deferred_refund_rejected_charge_failed

The Gateway applies the ach_deferred_refund_rejected_charge_failed error code to an eCheck refund if the parent charge was not settled when the refund was performed and the parent charge later fails to settle.

Level
error
HTTP Status Code
Unaffected by message

ach_invalid_merchant_configuration

The Gateway returns an ach_invalid_merchant_configuration error code if an eCheck transaction cannot be carried out successfully due to a configuration issue with the associated eCheck merchant account. Contact the Tenant that provisioned the account to resolve the issue. The ID of the failed transaction is returned in the entity_id property.

Level
error
HTTP Status Code
500

Example

{
      "messages": [
          {
              "code": "ach_invalid_merchant_configuration",
              "level": "error",
              "facility": "gateway",
              "entity_id": "jCEP6Mn3Q2Cg4nS3qqqDuw"
          }
      ]
  }
  

ach_processor_not_available

If the Gateway cannot communicate with the eCheck processor associated with a Merchant eCheck account to carry out a request, an ach_processor_not_available error is returned. This is typically a transient problem and can be retried at a later time. The ID of the failed transaction is returned in the entity_id property.

Level
error
HTTP Status Code
500

Example

{
      "messages": [
          {
              "code": "ach_processor_not_available",
              "level": "error",
              "facility": "gateway",
              "entity_id": "jCEP6Mn3Q2Cg4nS3qqqDuw"
          }
      ]
  }
  

ach_processing_error

If an eCheck processor reports a failure to process a request on behalf of the Gateway, an ach_processing_error error is returned to the caller. Unlike failures to communicate with the processor, retrying the operation may not resolve the issue. The ID of the failed transaction is returned in the entity_id property.

Level
error
HTTP Status Code
500

Example

{
      "messages": [
          {
              "code": "ach_processing_error",
              "level": "error",
              "facility": "payment_processor",
              "entity_id": "jCEP6Mn3Q2Cg4nS3qqqDuw"
          }
      ]
  }
  

Recurring Charge Messages

The following message codes are returned to indicate problems processing recurring charge requests submitted to the Gateway.

no_occurrences_for_schedule

If the schedule provided for the creation of a new recurring charge would result in no occurrences of scheduled payments, the Gateway returns a no_occurrences_for_schedule error and rejects the request.

Level
error
HTTP Status Code
422

Example

{
      ...
      "messages": [
          {
              "code": "no_occurrences_for_schedule",
              "level": "error",
              "facility": "gateway"
          }
      ]
  }
  

first_occurrence_due_immediately

If the schedule provided for the creation of a new recurring charge would result in a payment due today, the Gateway returns a first_occurrence_due_immediately error and rejects the request. The schedule must be updated such that the first occurrence is due no sooner than the day following the current day.

Level
error
HTTP Status Code
422

Example

{
      ...
      "messages": [
          {
              "code": "first_occurrence_due_immediately",
              "level": "error",
              "facility": "gateway"
          }
      ]
  }
  

update_results_in_no_occurrences

If the schedule provided for the update of an existing recurring charge would result in no further occurrences of scheduled payments, the Gateway returns a update_results_in_no_occurrences error and rejects the request. In this case, the Merchant can cancel the recurring charge instead to prevent any further attempts to collect payments.

Level
error
HTTP Status Code
422

Example

{
      ...
      "messages": [
          {
              "code": "update_results_in_no_occurrences",
              "level": "error",
              "facility": "gateway"
          }
      ]
  }
  

Webhooks

Payment integrations often need to know when changes occur to the objects manipulated by the API. For example, after a Charge is authorized, the merchant may have an external system that needs to know whether the Charge was later captured successfully. Webhooks address this problem by allowing the caller to register a URL to which the Gateway POSTs events corresponding to changes within the Gateway. As changes occur within the Gateway, events are created describing what changed. The Gateway then checks whether any webhook URLs are registered and, for each URL, performs an HTTP POST containing the Event data in JSON format. The Event JSON sent to the webhook is identical to the content retrieved using the Events APIs.

Configuring Webhooks

You configure the URLs to which events are POSTed by setting the live_events_urls and test_events_urls properties of your merchant object. This is accomplished via the Update Merchant endpoint. The URL to which events are POSTed depends on the test vs live mode of the change. Changes that have a mode, such as transactions, are sent to the URL corresponding to that mode. For example, changes to test mode transactions are sent to the URLs registered with the test_events_urls property, while changes to live mode transactions are sent to the URLs defined by live_events_urls. Changes that aren't associated with either mode are sent to both sets of URLs.

You may specify any URL you wish to receive Events. Keep in mind that while no sensitive payment details are ever communicated in the Event data, personally identifiable information such as customer names and addresses may be included. For this reason, we strongly recommend using the HTTPS scheme for all URLs.

Receiving Events

Configuring your system to receive Events via the Gateway's webhooks is as simple as defining a URL capable of handling a POST request. For example, in a Ruby on Rails application, you would define a new route and associated controller to receive the Event.

Webhook notifications may come from the following IP addresses:

  • 3.222.94.175
  • 18.204.61.234
  • 18.204.91.219
  • 18.205.139.79
  • 23.22.208.45
  • 34.198.45.60
  • 34.205.211.204
  • 34.233.131.21
  • 34.234.254.36
  • 44.207.66.183
  • 50.16.165.157
  • 52.55.65.238
  • 52.200.149.143
  • 54.80.246.184
  • 54.84.57.224
  • 54.156.200.152
  • 54.163.74.37
  • 54.165.103.176
  • 54.172.53.80
  • 54.173.15.63
  • 54.174.131.184
  • 100.24.202.220
  • 100.24.207.245
  • 100.25.247.142

You must configure your server to receive and respond to webhook POST requests. AffiniPay is expecting HTTP status codes in response to webhooks. If your server doesn't respond with a 200 OK message after receiving an event, AffiniPay will attempt to resend the event a maximum of 6 times, with an initial 1-hour delay that increases by 1 hour for each failed attempt (e.g., first attempt at time t0, second attempt at t0 + 1 hour, third attempt at t0 + 2 hours, etc).

Event POSTs contain the full Event content as JSON formatted data in the request body. Because the URL receiving the webhook request is publicly visible, we recommend that integrating systems track previously processed Event IDs to avoid any possible replay attacks from external parties. External systems that require trust in the Event data should only treat the received webhook as a hint and always retrieve the Event content from the Gateway directly, using the Events API.

Event Types

The Gateway generates the following Events. The data content described for each Event is accessed from the data property of the event.

transaction.authorized

A transaction.authorized event is generated when a transaction has been accepted by the Gateway. For Charges, this Event is generated after successfully authorizing the payment with the payment processing network (checking for availability of funds, etc). The corresponding Transaction is included in the content of the event's data property.

Example

{
      "id": "3mLZet76SrOMg0Gs3QsTbA",
      "created": "2016-10-25T18:08:22.811Z",
      "type": "transaction.authorized",
      "data": {
          "id": "S-EdSnl0RCmPjlCNcc8MSA",
          "created": "2016-10-25T18:08:22.555Z",
          "modified": "2016-10-25T18:08:22.806Z",
          "account_id": "TU0BOD2gEeOfvhLxg70sog",
          "status": "AUTHORIZED",
          "amount": 1312,
          "currency": "USD",
          "authorization_code": "ZBZTGZ",
          "auto_capture": true,
          "amount_refunded": 0,
          "cvv_result": "MATCHED",
          "avs_result": "ADDRESS_AND_POSTAL_CODE",
          "type": "CHARGE",
          "method": {
              "name": "Some Customer",
              "address1": "123 Main St",
              "postal_code": "78730",
              "type": "card",
              "number": "************4242",
              "fingerprint": "GunPelYVthifNV63LEw1",
              "card_type": "VISA",
              "exp_month": 10,
              "exp_year": 2025,
              "cvv": "***"
          }
      }
  }
  

transaction.completed

After the Gateway successfully completes the processing on a transaction, a transaction.completed Event is generated. This Event indicates the transaction has been captured by the payment processing network associated with the transaction's Account and funds settlement initiated. The corresponding Transaction is included in the content of the Event's data property.

Example

{
      "id": "gSebwTS4TSCDDAINhYVirA",
      "created": "2019-10-25T18:08:22.811Z",
      "type": "transaction.completed",
      "data": {
          "id": "KZ785OcOT9eKrd9vYUHSIg",
          "created": "2019-10-25T05:00:00.322Z",
          "modified": "2019-10-25T05:00:00.322Z",
          "account_id": "TU0BOD2gEeOfvhLxg70sog",
          "status": "COMPLETED",
          "completion_timestamp": "2019-11-25T05:14:27.000-06:00",
          "amount": 100,
          "currency": "USD",
          "charge_id": "1N6tYslhQ-GBj7y2hxcCoA",
          "reference": "credit ref",
          "type": "REFUND",
          "invoice_id": i_LiGDAYi60vgvmRhciiUJh".
          "method": {
              "name": "Some Customer",
              "type": "card",
              "number" : "***********0005",
              "fingerprint": "wwJwEqfK1cM6fnqKeb2K",
              "card_type": "AMERICAN_EXPRESS",
              "exp_month": 10,
              "exp_year": 2025,
              "cvv": "***"
          }
      }
  }
  

transaction.voided

A transaction.voided Event is generated whenever a transaction is voided, either by the caller or automatically by the Gateway. The corresponding Transaction is included in the content of the event's data property.

Example

{
      "id": "LMvWZZ8MTYyVBr7hjoohEg",
      "created": "2016-10-25T20:48:21.814Z",
      "type": "transaction.voided",
      "data": {
          "id": "A-TyJgSnTiCGVP6qYdovFw",
          "created": "2016-10-25T20:48:21.713Z",
          "modified": "2016-10-25T20:48:21.754Z",
          "account_id": "NRnwSWCzRy69rIyvkVRIUA",
          "status": "VOIDED",
          "amount": 100,
          "currency": "USD",
           "authorization_code": "FZTINF",
          "void_reference": "void ref",
          "auto_capture": true,
          "amount_refunded": 0,
          "type": "CHARGE",
          "method": {
              "name": "Some Customer",
              "type": "card",
              "number": "************4242",
              "fingerprint": "GunPelYVthifNV63LEw1",
              "card_type": "VISA",
              "exp_month": 10,
              "exp_year": 2025
          }
      }
  }
  

transaction.failed

If a transaction fails for any reason after initial authorization (for example, due to a capture failure), the Gateway generates a transaction.failed event. The corresponding transaction is included in the content of the event's data property.

Example

{
      "id": "-vScpwCpQimM274I5L_l6A",
      "created": "2016-10-25T20:59:39.123Z",
      "type": "transaction.failed",
      "data": {
          "id": "Jw0ckpWdQRWznCa3LrLVig",
          "created": "2016-10-25T20:59:39.071Z",
          "modified": "2016-10-25T20:59:39.115Z",
          "account_id": "E9EK1fr_ScilXxuEmXmjDg",
          "status": "FAILED",
          "failure_code": "settlement_failed",
          "amount": 34,
          "currency": "USD",
          "auto_capture": false,
          "amount_refunded": 0,
          "type": "CHARGE",
          "method": {
              "name": "Some Customer",
              "type": "card",
              "number": "************0010",
              "fingerprint": "b2HMkkyEWX8uLCb-CSJH",
              "card_type": "VISA",
              "exp_month": 10,
              "exp_year": 2025
          }
      }
  }
  

transaction.updated

Any change made to a transaction that does not also change the status of the transaction results in a transaction.updated event being created. (For example, conversion of a manual capture transaction to auto-capture.) The content of the transaction is included in the event's data property.

Example

{
      "id": "pEloF72XTaOyKfANlEecYg",
      "created": "2016-05-19T21:01:44.574Z",
      "type": "transaction.updated",
      "data": {
          "id": "Op5rO2BMSLGaIxrgxWAHXQ",
          "created": "2016-05-19T21:01:44.528Z",
          "modified": "2016-05-19T21:01:44.538Z",
          "account_id": "1XjA19cTScWXYjvmQF3LNA",
          "status": "AUTHORIZED",
          "amount": 5500,
          "currency": "USD",
          "authorization_code": "DIIL4A",
          "auto_capture": true,
          "type": "CHARGE",
          "method": {
              "name": "Some Customer",
              "type": "card",
              "number": "************0010",
              "fingerprint": "b2HMkkyEWX8uLCb-CSJH",
              "card_type": "VISA",
              "exp_month": 10,
              "exp_year": 2025
          }
      }
  }
  

transaction.pending_parent_settlement

Authorization of eCheck Refunds is deferred until the parent Charge is settled. This ensures that funds are not returned until they are guaranteed to have been available. As a result, unlike with other transactions, no initial transaction.authorized event is created. Instead, a transaction.pending_parent_settlement event is created to mark the creation of the deferred refund. The refund is included in the content of the event's data property.

Example

{
      "id": "monKKds7TgumHbbf0rQXmw",
      "created": "2016-05-19T11:32:18.024Z",
      "type": "transaction.pending_parent_settlement",
      "data": {
          "id": "gq5YQllXSEihD_7Pqthovg",
          "created": "2016-05-19T11:32:17.967Z",
          "modified": "2016-05-19T11:32:18.012Z",
          "account_id": "E9EK1fr_ScilXxuEmXmjDg",
          "status": "PENDING",
          "amount": 1200,
          "currency": "USD",
          "authorization_code": "DIIL4A",
          "auto_capture": true,
          "type": "REFUND",
          "method": {
              "name": "Customer Inc",
              "account_holder_type": "business",
              "type": "bank",
              "routing_number": "******013",
              "account_number": "******7890",
              "account_type": "CHECKING",
              "bank_name": "FIRST BANK OF TESTING",
              "fingerprint": "8c-uVB-K0R8KnItE1Ri4"
          }
      }
  }
  

payment_method.expiring

Saved customer payment methods that contain expiration dates, such as card, generate payment_method.expiring events prior to expiration. For cards, the expiring event is sent on the first day of the month in which the card expires. The payment method is included in the content of the event's data property.

Example

{
      "id": "1VDRNOPLT82SO1BTnZqzRw",
      "created": "2016-12-01T03:00:01.127Z",
      "type": "payment_method.expiring",
      "data": {
          "id": "_2xcfBTLTlS_zonNe4j8CA",
          "created": "2016-12-03T02:43:49.127Z",
          "modified": "2016-12-03T02:43:49.127Z",
          "type": "card",
          "name": "Some Customer",
          "number": "************4242",
          "card_type": "VISA",
          "exp_month": 11,
          "exp_year": 2017,
      }
  }
  

payment_method.expired

Saved customer payment methods that contain expiration dates, such as card, generate payment_method.expired events upon expiration. For cards, the expired event is sent on the first day of the month following the card expiration month. The payment method is included in the content of the event's data property.

Example

{
      "id": "O5r6bWvHQZ2kW3QjAMV6Xg",
      "created": "2016-12-01T03:00:03.842Z",
      "type": "payment_method.expired",
      "data": {
          "id": "__v0aP-_QfKsD61ZBkcjPg",
          "created": "2016-11-21T03:01:10.485Z",
          "modified": "2016-11-21T03:01:10.485Z",
          "type": "card",
          "name": "Some Customer",
          "number": "************4242",
          "card_type": "VISA",
          "exp_month": 12,
          "exp_year": 2017,
      }
  }
  

payment_method.updated

When a saved payment method is updated by account updater, an event is generated. A card is updated when its expiration date or card number has changed.

Level
error
HTTP Status Code
422

Example

{
        "id": "1VDRNOPLT82SO1BTnZqzRw",
        "created": "2016-12-01T03:00:01.127Z",
        "type": "payment_method.updated",
        "data": {
          "id": "_2xcfBTLTlS_zonNe4j8CA",
          "created": "2016-12-03T02:43:49.127Z",
          "modified": "2016-12-03T02:43:49.127Z",
          "type": "card",
          "name": "Some Customer",
          "number": "************4242",
          "card_type": "VISA",
          "exp_month": 11,
          "exp_year": 2017,
        }
  }
  

payment_method.closed

When a saved payment method is closed by account updater, an event is generated. A card is closed when the account has been permanently closed by the issuing bank or the card has been updated but the cardholder has requested that the issuer not share updated card details.

Level
error
HTTP Status Code
422

Example

{
        "id": "1VDRNOPLT82SO1BTnZqzRw",
        "created": "2016-12-01T03:00:01.127Z",
        "type": "payment_method.closed",
        "data": {
          "id": "_2xcfBTLTlS_zonNe4j8CA",
          "created": "2016-12-03T02:43:49.127Z",
          "modified": "2016-12-03T02:43:49.127Z",
          "type": "card",
          "name": "Some Customer",
          "number": "************4242",
          "card_type": "VISA",
          "exp_month": 11,
          "exp_year": 2017,
        }
  }
  

recurring_charge.created

A recurring_charge.created event is generated whenever a new recurring charge is created. The recurring charge instance is included in the content of the event's data property.

Example

{
      "id": "N0DbatMOTjm8FuPRTKm0uA",
      "created": "2016-07-01T01:55:12.468Z",
      "type": "recurring_charge.created",
      "data": {
          "id": "DUPzt5y7RVGmnSW4BJegbQ",
          "status": "ACTIVE",
          "account_id": "D5qNOhlwSNK7IV2-HtSAdA",
          "method": {
              "type": "card",
              "number": "************4242",
              "fingerprint": "GunPelYVthifNV63LEw1",
              "card_type": "VISA",
              "exp_month": 10,
              "exp_year": 2025,
              "name": "Test Customer",
              "address1": "123 Main St",
              "postal_code": "78730"
          },
          "schedule": {
              "interval_unit": "MONTH",
              "interval_delay": 1,
              "start": "2020-01-01"
          },
          "description": "New Recurring Charge",
          "amount": 145,
          "currency": "USD",
          "total_occurrences": 0,
          "total_amount": 0,
          "next_payment": "2020-01-01"
      }
  }
  

recurring_charge.updated

Following an update to a recurring charge, a recurring_charge.updated event is generated. The event's data property contains the contents of the updated recurring charge.

Example

{
      "id": "ekJpirwHRfOCN05P2jKEUA",
      "created": "2016-07-01T01:59:36.664Z",
      "type": "recurring_charge.updated",
      "data": {
          "id": "DUPzt5y7RVGmnSW4BJegbQ",
          "status": "ACTIVE",
          "account_id": "D5qNOhlwSNK7IV2-HtSAdA",
          "method": {
              "type": "card",
              "number": "************4242",
              "fingerprint": "GunPelYVthifNV63LEw1",
              "card_type": "VISA",
              "exp_month": 8,
              "exp_year": 2025,
              "name": "Test Customer",
              "address1": "123 Main St",
              "postal_code": "78730"
          },
          "schedule": {
              "interval_unit": "MONTH",
              "interval_delay": 1,
              "start": "2020-01-01"
          },
          "description": "New Recurring Charge",
          "amount": 150,
          "currency": "USD",
          "total_occurrences": 0,
          "total_amount": 0,
          "next_payment": "2020-01-01"
      }
  }
  

recurring_charge.deleted

A recurring_charge.deleted event is generated following the deletion of a recurring charge. The latest content of the recurring charge instance is included in the content of the event's data property.

Example

{
      "id": "aN1pQwDBS1CPAinoYHLrpg",
      "created": "2016-07-01T03:14:08.919Z",
      "type": "recurring_charge.deleted",
      "data": {
          "id": "DUPzt5y7RVGmnSW4BJegbQ",
          "status": "DELETED",
          "account_id": "D5qNOhlwSNK7IV2-HtSAdA",
          "method": {
              "type": "card",
              "number": "************4242",
              "fingerprint": "GunPelYVthifNV63LEw1",
              "card_type": "VISA",
              "exp_month": 10,
              "exp_year": 2025,
              "name": "Test Customer",
              "address1": "123 Main St",
              "postal_code": "78730"
          },
          "schedule": {
              "interval_unit": "MONTH",
              "interval_delay": 1,
              "start": "2020-01-01"
          },
          "description": "New Recurring Charge",
          "amount": 150,
          "currency": "USD",
          "total_occurrences": 2,
          "total_amount": 300,
          "next_payment": "2020-03-01"
      }
  }
  

recurring_charge.completed

The completion of a recurring charge, either due to attempted payment of all scheduled occurrences or user cancellation, creates a recurring_charge.completed event. The event's data property contains the content of the completed recurring charge.

Example

{
      "id": "aN1pQwDBS1CPAinoYHLrpg",
      "created": "2019-11-01T03:10:54.236Z",
      "type": "recurring_charge.completed",
      "data": {
          "id": "DUPzt5y7RVGmnSW4BJegbQ",
          "status": "COMPLETED",
          "completion_timestamp": "2019-11-01T05:14:27.000-06:00",
          "status_reason": "user_canceled",
          "account_id": "D5qNOhlwSNK7IV2-HtSAdA",
          "method": {
              "type": "card",
              "number": "************4242",
              "fingerprint": "GunPelYVthifNV63LEw1",
              "card_type": "VISA",
              "exp_month": 10,
              "exp_year": 2025,
              "name": "Test Customer",
              "address1": "123 Main St",
              "postal_code": "78730"
          },
          "schedule": {
              "interval_unit": "MONTH",
              "interval_delay": 1,
              "start": "2020-01-01"
          },
          "description": "New Recurring Charge",
          "amount": 150,
          "currency": "USD",
          "total_occurrences": 2,
          "total_amount": 300,
          "next_payment": "2020-03-01"
      }
  }
  

recurring_charge.payment_method.expiring

Similar to the payment_method.expiring event for saved payment methods, the Gateway generates recurring_charge.payment_method.expiring events to notify merchants of the upcoming expiration of the payment method associated with a recurring charge. These events are sent on the first day of the month in which the payment method expires. The data property of the event contains the JSON content of the affected recurring charge.

Example

{
      "id": "Gd2iejn8SemQ7gYfxb1aaQ",
      "created": "2016-06-01T00:00:00.277Z",
      "type": "recurring_charge.payment_method.expiring",
      "data": {
          "id": "OAe6YaS7TPiRtJiM1USqDg",
          "status": "ACTIVE",
          "account_id": "D5qNOhlwSNK7IV2-HtSAdA",
          "method": {
              "type": "card",
              "number": "************4242",
              "fingerprint": "GunPelYVthifNV63LEw1",
              "card_type": "VISA",
              "exp_month": 11,
              "exp_year": 2017
              "name": "Test Customer",
              "address1": "123 Main St",
              "postal_code": "78730"
          },
          "schedule": {
              "interval_unit": "MONTH",
              "interval_delay": 1,
              "start": "2016-05-01"
          },
          "description": "New Recurring Charge",
          "amount": 2500,
          "currency": "USD",
          "total_occurrences": 1,
          "total_amount": 2500,
          "next_payment": "2016-06-01"
      }
  }
  

recurring_charge.payment_method.expired

Upon expiration of the payment method associated with a recurring charge, the Gateway creates a recurring_charge.payment_method.expired event to notify merchants of the need to update the payment method. Without an update to the payment details, future scheduled attempts to collect payment for the recurring charge are likely to fail. These events are sent on the first day of the month following the expiration of the payment method. The data property of the Event contains the JSON content of the affected recurring charge.

Example

{
      "id": "07RRZ2aESqedDKcyqfEWMQ",
      "created": "2016-07-01T00:00:00.193Z",
      "type": "recurring_charge.payment_method.expired",
      "data": {
          "id": "OAe6YaS7TPiRtJiM1USqDg",
          "status": "ACTIVE",
          "account_id": "D5qNOhlwSNK7IV2-HtSAdA",
          "method": {
              "type": "card",
              "number": "************4242",
              "fingerprint": "GunPelYVthifNV63LEw1",
              "card_type": "VISA",
              "exp_month": 12,
              "exp_year": 2017
              "name": "Test Customer",
              "address1": "123 Main St",
              "postal_code": "78730"
          },
          "schedule": {
              "interval_unit": "MONTH",
              "interval_delay": 1,
              "start": "2016-05-01"
          },
          "description": "New Recurring Charge",
          "amount": 2500,
          "currency": "USD",
          "total_occurrences": 2,
          "total_amount": 2500,
          "next_payment": "2016-07-01"
      }
  }
  

recurring_charge.payment_method.updated

Similar to the payment_method.updated event for saved payment methods, the Gateway generates an recurring_charge.payment_method.updated event when a saved payment method is updated by account updater. A card is updated when its expiration date or card number has changed.

Level
error
HTTP Status Code
422

Example

{
      "id": "Gd2iejn8SemQ7gYfxb1aaQ",
      "created": "2016-06-01T00:00:00.277Z",
      "type": "recurring_charge.payment_method.updated",
      "data": {
          "id": "OAe6YaS7TPiRtJiM1USqDg",
          "status": "ACTIVE",
          "account_id": "D5qNOhlwSNK7IV2-HtSAdA",
          "method": {
              "type": "card",
              "number": "************4242",
              "fingerprint": "GunPelYVthifNV63LEw1",
              "card_type": "VISA",
              "exp_month": 11,
              "exp_year": 2025
              "name": "Test Customer",
              "address1": "123 Main St",
              "postal_code": "78730",
              "status": "OPEN"
          },
          "schedule": {
              "interval_unit": "MONTH",
              "interval_delay": 1,
              "start": "2016-05-01"
          },
          "description": "New Recurring Charge",
          "amount": 2500,
          "currency": "USD",
          "total_occurrences": 1,
          "total_amount": 2500,
          "next_payment": "2016-06-01"
      }
  }
  

recurring_charge.payment_method.closed

When saved payment method associated with a recurring charge is closed by account updater, an event is generated. A card is closed when the account has been permanently closed by the issuing bank or the card has been updated but the cardholder has requested that the issuer not share updated card details.

Level
error
HTTP Status Code
422

Example

{
      "id": "07RRZ2aESqedDKcyqfEWMQ",
      "created": "2016-07-01T00:00:00.193Z",
      "type": "recurring_charge.payment_method.closed",
      "data": {
          "id": "OAe6YaS7TPiRtJiM1USqDg",
          "status": "ACTIVE",
          "account_id": "D5qNOhlwSNK7IV2-HtSAdA",
          "method": {
              "type": "card",
              "number": "************4242",
              "fingerprint": "GunPelYVthifNV63LEw1",
              "card_type": "VISA",
              "exp_month": 12,
              "exp_year": 2017
              "name": "Test Customer",
              "address1": "123 Main St",
              "postal_code": "78730",
              "status": "CLOSED"
          },
          "schedule": {
              "interval_unit": "MONTH",
              "interval_delay": 1,
              "start": "2016-05-01"
          },
          "description": "New Recurring Charge",
          "amount": 2500,
          "currency": "USD",
          "total_occurrences": 2,
          "total_amount": 2500,
          "next_payment": "2016-07-01"
      }
  }
  

recurring_charge.occurrence.created

In response to the creation of a new recurring charge occurrence, a corresponding recurring_charge.occurrence.created event is also created. Note that the creation of any recurring charge will also create the initial occurrence for that recurring charge, resulting in at least two events (and possibly more if the initial occurrence is paid immediately). The event's data property contains the JSON content of the newly created occurrence.

Example

{
      "id": "3nA46a9yQAKF4A7kVcThyA",
      "created": "2016-07-01T01:55:12.473Z",
      "type": "recurring_charge.occurrence.created",
      "data": {
          "id": "LDJtMP40T6WXLPYJxlsMQQ",
          "recurring_charge_id": "DUPzt5y7RVGmnSW4BJegbQ",
          "amount": 145,
          "status": "PENDING",
          "due_date": "2020-01-01",
          "attempts": 0
      }
  }
  

recurring_charge.occurrence.updated

Changes to a recurring charge can result in the current pending occurrence (that is, the occurrence associated with the next payment due) to be updated as well. For example, changes to the amount to be collected for each payment, or the collection schedule, can impact the next payment. Updates such as these cause a new recurring_charge.occurrence.updated event to be created, containing the updated version of the occurrence in the data property of the event.

Example

{
      "id": "ifm_2OFVT3iw6H9tHE0IFg",
      "created": "2016-07-01T01:59:36.669Z",
      "type": "recurring_charge.occurrence.updated",
      "data": {
          "id": "LDJtMP40T6WXLPYJxlsMQQ",
          "recurring_charge_id": "DUPzt5y7RVGmnSW4BJegbQ",
          "amount": 150,
          "status": "PENDING",
          "due_date": "2020-01-01",
          "attempts": 0
      }
  }
  

recurring_charge.occurrence.paid

When a transaction is successfully authorized to collect payment for a recurring charge occurrence, a recurring_charge.occurrence.paid event is created. The event's data property contains the content of the recurring charge occurrence, which includes the authorized transaction in the occurrence's transactions property.

Example

{
      "id": "6ld6VsL9TJaSU_kRYCJUFA",
      "created": "2016-07-01T02:05:13.621Z",
      "type": "recurring_charge.occurrence.paid",
      "data": {
          "id": "LDJtMP40T6WXLPYJxlsMQQ",
          "recurring_charge_id": "DUPzt5y7RVGmnSW4BJegbQ",
          "amount": 150,
          "status": "PAID",
          "due_date": "2020-01-01",
          "attempts": 2,
          "last_attempt": "2016-07-01T02:05:13.402Z",
          "transactions": [ {
              "id": "-EMvccWnR523IY1UIPIb6g",
              "account_id": "D5qNOhlwSNK7IV2-HtSAdA",
              "status": "AUTHORIZED",
              "auto_capture": true,
              "amount": 150,
              "currency": "USD",
              "method": {
                  "type": "card",
                  "number": "************4242",
                  "fingerprint": "GunPelYVthifNV63LEw1",
                  "card_type": "VISA",
                  "exp_month": 8,
                  "exp_year": 2025,
                  "name": "Test Customer",
                  "address1": "123 Main St",
                  "postal_code": "78730"
              },
              "amount_refunded": 0,
              "recurring_charge_id": "DUPzt5y7RVGmnSW4BJegbQ",
              "recurring_charge_occurrence_id": "LDJtMP40T6WXLPYJxlsMQQ",
              "type": "CHARGE"
          } ]
      }
  }
  

recurring_charge.occurrence.failed

A recurring_charge.occurrence.failed event is generated when an attempt to pay (either automatically by the Gateway on the occurrence's due date, or as a result of the Merchant pre-paying the occurrence via the API) fails. A failure to collect payment is any case in which a transaction could not be successfully authorized for the scheduled amount. The event's data property contains the content of the recurring charge occurrence. The failing transaction is included in the occurrence's transactions property.

Example

{
      "id": "P3o15YPsStGFinlee7Z2Lg",
      "created": "2016-07-01T02:03:21.808Z",
      "type": "recurring_charge.occurrence.failed",
      "data": {
          "id": "LDJtMP40T6WXLPYJxlsMQQ",
          "recurring_charge_id": "DUPzt5y7RVGmnSW4BJegbQ",
          "amount": 150,
          "status": "FAILED",
          "due_date": "2020-01-01",
          "attempts": 1,
          "last_attempt": "2016-07-01T02:03:21.649Z",
          "transactions": [ {
              "id": "In0wV4VtRRqLieI0N6L1Jg",
              "account_id": "D5qNOhlwSNK7IV2-HtSAdA",
              "status": "FAILED",
              "failure_code": "card_declined",
              "auto_capture": true,
              "amount": 150,
              "currency": "USD",
              "method": {
                  "type": "card",
                  "number": "************4242",
                  "fingerprint": "GunPelYVthifNV63LEw1",
                  "card_type": "VISA",
                  "exp_month": 8,
                  "exp_year": 2025,
                  "name": "Test Customer",
                  "address1": "123 Main St",
                  "postal_code": "78730"
              },
              "amount_refunded": 0,
              "recurring_charge_id": "DUPzt5y7RVGmnSW4BJegbQ",
              "recurring_charge_occurrence_id": "LDJtMP40T6WXLPYJxlsMQQ",
              "type": "CHARGE"
          } ]
      }
  }
  

recurring_charge.occurrence.ignored

Marking a recurring charge occurrence ignored creates a new recurring_charge.occurrence.ignored event. The event's data property contains the content of the occurrence.

Example

{
      "id": "VzWIEdExS-qQs-pnNcuxdA",
      "created": "2016-07-01T02:06:18.174Z",
      "type": "recurring_charge.occurrence.ignored",
      "data": {
          "id": "LDJtMP40T6WXLPYJxlsMQQ",
          "recurring_charge_id": "DUPzt5y7RVGmnSW4BJegbQ",
          "amount": 150,
          "status": "IGNORED",
          "due_date": "2020-01-01",
          "attempts": 0
      }
  }
  

Contact API

Overview

The AffiniPay Payment Platform provides a REST API to enable you to create contacts and payment methods.

For a successful integration, you should be familiar with writing code that interacts with REST endpoints using the HTTP protocol as well as the OAuth 2.0 Authorization Framework.

Authentication

The AffiniPay Payment Platform authorizes requests using OAuth 2.0, which identifies and authenticates your partner OAuth application using your OAuth client ID and OAuth client secret. Both are available in the AffiniPay web application.

When you run the OAuth flow, the AffiniPay Payment Platform returns a bearer access token that authenticates your API requests. You must include this access token in API requests in the Authorization header with the Bearer authentication scheme. See the Connect topics to determine which OAuth flow to use.

Testing

Before you put your integration into production use, you should test with a variety of valid and invalid request data to exercise both success and failure scenarios in your application. To make test requests, set the test_mode parameter on each object to true.

Requests and Responses

The Contact REST API only accepts encrypted communications using HTTPS; requests made over unsecured HTTP communications are not accepted. All interactions with the REST API are carried out over a secure connection using TLS 1.2 to safeguard data contents.

All request and response content is represented as JSON.

Requests are standard REST calls made to the Payment Portal API URL:

https://api.affinipay.com

The REST API returns standard HTTP status codes to indicate the success or failure of each operation. Status codes in the 2xx family indicate success, the 4xx family indicates a failure stemming from the data provided in the request, and the 5xx family indicates that the failure is outside the caller's control.

Response CodeDescription
200The operation succeeded
204The operation succeeded, but no response content was returned (normal for APIs that do not return any JSON response).
400The request was malformed.
401Authentication credentials were not provided, or were not valid for the requested operation.
404An item referred to in the request, such as a charge or merchant bank account, was not found.
409There was a state conflict due to an unsupported action, such as an attempt to delete an invoice with a payment or an attempt to create an object that already exists.
422The request could not be processed. This is typically due to validation errors reported in the response.
500An error occurred while processing the request.

Contacts

A Contact is an entity (representing a person or business organization) that acts within the AffiniPay Payment Portal system. A Contact can have PaymentMethods that specify payment details.

Search Contacts

GET /contacts

Retrieves a list that includes each Contact that matches the search criteria provided.

Query parameters

ParameterTypeDescription
qStringThe text filter to apply across all text fields. (optional)
qfStringThe filters to apply against specific fields, in the format field:value. If a field is nested, the dot-separated path must be specified. For example, to search for the time when an invoice was created, use created.timestamp; to search for the status of an invoice, use status. Multiple field:value pairs should be separated by a comma, qf=f1:v1,f2:v2,...fn:vn. Date ranges can be queried using >, >=, <, <= in the format timestamp(>|>=|<|<=)value. The date value to query against must be in the format yyyy-MM-ddTHH:mm:ss.SSSZZ. For example, created.timestamp>2018-06-25T15:45:57.838Z or modified.timestamp<=2017-11-14T12:25:58.891Z. A date range with two bounds should be separated by a comma, qf=f1(>|>=|<|<=)v1,f1(>|>=|<|<=)v2. (optional)
order_byArray of StringThe list of fields to sort by, prefixed with - for descending. To include multiple fields, separate them with a comma. For example, order_by=field1,-field2. (optional)
pageInt32The page number, starting at 1. The default value is 1. (optional)
page_sizeInt32The maximum number of items in the page. (optional)
Search for all contacts
curl -X GET "Authorization: Bearer <access_token>" https://api.affinipay.com/contacts
Example response
{
    "page": 1,
    "page_size": 20,
    "total_entries": 200,
    "results": [
        {
            "id": "p_tup7e7S0e7LIE55qvgXAR",
            "created": {
                "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
                "timestamp": "2018-06-07T16:22:17.445Z",
                "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
                "client_inet_address": "66.90.249.23",
                "client_country_code": "US",
                "client_location": "30.2414,-97.7687",
                "caller_inet_address": "66.90.249.23",
                "caller_country_code": "US",
                "caller_location": "30.2414,-97.7687"
            },
            "modified": {
                "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
                "timestamp": "2018-06-07T16:22:17.445Z",
                "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
                "client_inet_address": "66.90.249.23",
                "client_country_code": "US",
                "client_location": "30.2414,-97.7687",
                "caller_inet_address": "66.90.249.23",
                "caller_country_code": "US",
                "caller_location": "30.2414,-97.7687"
            },
            "test_mode": false,
            "name": "Ellen Ripley",
            "sort_name": "Ripley Ellen",
            "preferred_email": "eripley@example.com",
            "contact_code": "0010",
            "owner_id": "org_Y2eJHCXVqjMlXL9EfmBfc",
            "owner": {
                "id": "org_Y2eJHCXVqjMlXL9EfmBfc",
                "test_mode": false,
                "owner_id": "org_aQ5urhpA1HUBJIxAvDfsM",
                "preferred_email": "myemail@example.com",
                "name": "My Company",
                "sort_name": "My Company",
                "type": "organization",
                "display_name": "My Company"
            },
            "email_addresses": [
                {
                    "id": "eml_mh5lADCijYgvLf5pMVvDl",
                    "created": {
                        "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
                        "timestamp": "2018-06-07T16:22:17.446Z",
                        "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
                        "client_inet_address": "66.90.249.23",
                        "client_country_code": "US",
                        "client_location": "30.2414,-97.7687",
                        "caller_inet_address": "66.90.249.23",
                        "caller_country_code": "US",
                        "caller_location": "30.2414,-97.7687"
                    },
                    "modified": {
                        "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
                        "timestamp": "2018-06-07T16:22:17.446Z",
                        "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
                        "client_inet_address": "66.90.249.23",
                        "client_country_code": "US",
                        "client_location": "30.2414,-97.7687",
                        "caller_inet_address": "66.90.249.23",
                        "caller_country_code": "US",
                        "caller_location": "30.2414,-97.7687"
                    },
                    "address": "eripley@example.com",
                    "preferred": false,
                    "type": "email_address"
                }
            ],
            "first_name": "Ellen",
            "last_name": "Ripley",
            "display_name": "Ellen Ripley",
            "type": "person"
        },
        .
        .
        .
        {
            "id": "p_AGx6xPaOQ9iLyjOHOYT5T",
            "created": {
                "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
                "timestamp": "2018-02-14T22:14:30.256Z",
                "client_inet_address": "172.30.2.0",
                "caller_inet_address": "172.30.2.0"
            },
            "modified": {
                "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
                "timestamp": "2018-02-14T22:14:30.302Z",
                "client_inet_address": "172.30.2.0",
                "caller_inet_address": "172.30.2.0"
            },
            "test_mode": false,
            "name": "John Conner",
            "sort_name": "Conner John",
            "preferred_email": "jconner@example.com",
            "contact_code": "0438",
            "owner_id": "org_Y2eJHCXVqjMlXL9EfmBfc",
            "owner": {
                "id": "org_Y2eJHCXVqjMlXL9EfmBfc",
                "test_mode": false,
                "owner_id": "org_aQ5urhpA1HUBJIxAvDfsM",
                "preferred_email": "myemail@example.com",
                "name": "My Partner Company",
                "sort_name": "My Partner Company",
                "type": "organization",
                "display_name": "My Partner Company"
            },
            "email_addresses": [
                {
                    "id": "eml_mh5lADCijYgvLf5pMVvDl",
                    "created": {
                        "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
                        "timestamp": "2018-06-07T16:22:17.446Z",
                        "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
                        "client_inet_address": "66.90.249.23",
                        "client_country_code": "US",
                        "client_location": "30.2414,-97.7687",
                        "caller_inet_address": "66.90.249.23",
                        "caller_country_code": "US",
                        "caller_location": "30.2414,-97.7687"
                    },
                    "modified": {
                        "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
                        "timestamp": "2018-06-07T16:22:17.446Z",
                        "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
                        "client_inet_address": "66.90.249.23",
                        "client_country_code": "US",
                        "client_location": "30.2414,-97.7687",
                        "caller_inet_address": "66.90.249.23",
                        "caller_country_code": "US",
                        "caller_location": "30.2414,-97.7687"
                    },
                    "address": "jconner@example.com",
                    "preferred": false,
                    "type": "email_address"
                }
            ],
            "first_name": "John",
            "last_name": "Conner",
            "display_name": "John Conner",
            "type": "person"
        }
}

  

Create Contact

POST /contacts

Creates a Contact using the properties included in the request.

  • To create a Person, the request must include the type field set to person and at least one of the following fields: first_name, last_name, or email_address.
  • To create an Organization, the request must include the type field set to organization and at least one of the following fields: name or email_address.
To display in AffiniPay's Card Vault, a Contact must have the tag: default.
Create contact
curl -X POST -H "Content-Type:application/json" "Authorization: Bearer <access_token>" https://api.affinipay.com/contacts -d '
  {
    "first_name": "Ellen",
    "last_name": "Ripley",
    "source_id": "partnername:contact-512",
    "email_addresses": [
    	{"address": "eripley@example.com"}
    ],
    "tags": [
        "default"
    ],
    "type": "person"
  }'
Example response
{
    "id": "p_tup7e7S0e7LIE55qvgXAR",
    "created": {
        "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
        "timestamp": "2018-06-07T16:22:17.445Z",
        "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
        "client_inet_address": "66.90.249.23",
        "client_country_code": "US",
        "client_location": "30.2414,-97.7687",
        "caller_inet_address": "66.90.249.23",
        "caller_country_code": "US",
        "caller_location": "30.2414,-97.7687"
    },
    "modified": {
        "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
        "timestamp": "2018-06-07T16:22:17.445Z",
        "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
        "client_inet_address": "66.90.249.23",
        "client_country_code": "US",
        "client_location": "30.2414,-97.7687",
        "caller_inet_address": "66.90.249.23",
        "caller_country_code": "US",
        "caller_location": "30.2414,-97.7687"
    },
    "test_mode": false,
    "name": "Ellen Ripley",
    "sort_name": "Ripley Ellen",
    "preferred_email": "eripley@example.com",
    "contact_code": "0010",
    "owner_id": "org_Y2eJHCXVqjMlXL9EfmBfc",
    "owner": {
        "id": "org_Y2eJHCXVqjMlXL9EfmBfc",
        "test_mode": false,
        "owner_id": "org_aQ5urhpA1HUBJIxAvDfsM",
        "preferred_email": "myemail@example.com",
        "name": "My Company",
        "sort_name": "My Company",
        "type": "organization",
        "display_name": "My Company"
    },
    "email_addresses": [
        {
            "id": "eml_mh5lADCijYgvLf5pMVvDl",
            "created": {
                "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
                "timestamp": "2018-06-07T16:22:17.446Z",
                "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
                "client_inet_address": "66.90.249.23",
                "client_country_code": "US",
                "client_location": "30.2414,-97.7687",
                "caller_inet_address": "66.90.249.23",
                "caller_country_code": "US",
                "caller_location": "30.2414,-97.7687"
            },
            "modified": {
                "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
                "timestamp": "2018-06-07T16:22:17.446Z",
                "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
                "client_inet_address": "66.90.249.23",
                "client_country_code": "US",
                "client_location": "30.2414,-97.7687",
                "caller_inet_address": "66.90.249.23",
                "caller_country_code": "US",
                "caller_location": "30.2414,-97.7687"
            },
            "address": "eripley@example.com",
            "preferred": false,
            "type": "email_address"
        }
    ],
    "tags": [
        "default"
    ],
    "first_name": "Ellen",
    "last_name": "Ripley",
    "display_name": "Ellen Ripley",
    "type": "person"
}
  

Get Contact

GET /contacts/{contact_id}

Retrieves the specified Contact.

URI parameters
ParameterDescription
contact_idThe system-generated ID of a specific contact. (ID prefix = org_ or p_) (required)
Search for contact
curl -X GET "Authorization: Bearer <access_token>" https://api.affinipay.com/contacts/p_tup7e7S0e7LIE55qvgXAR
Example response
{
    "id": "p_tup7e7S0e7LIE55qvgXAR",
    "created": {
        "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
        "timestamp": "2018-06-07T16:22:17.445Z",
        "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
        "client_inet_address": "66.90.249.23",
        "client_country_code": "US",
        "client_location": "30.2414,-97.7687",
        "caller_inet_address": "66.90.249.23",
        "caller_country_code": "US",
        "caller_location": "30.2414,-97.7687"
    },
    "modified": {
        "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
        "timestamp": "2018-06-07T16:22:17.445Z",
        "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
        "client_inet_address": "66.90.249.23",
        "client_country_code": "US",
        "client_location": "30.2414,-97.7687",
        "caller_inet_address": "66.90.249.23",
        "caller_country_code": "US",
        "caller_location": "30.2414,-97.7687"
    },
    "test_mode": false,
    "name": "Ellen Ripley",
    "sort_name": "Ripley Ellen",
    "preferred_email": "eripley@example.com",
    "contact_code": "0010",
    "owner_id": "org_Y2eJHCXVqjMlXL9EfmBfc",
    "owner": {
        "id": "org_Y2eJHCXVqjMlXL9EfmBfc",
        "test_mode": false,
        "owner_id": "org_aQ5urhpA1HUBJIxAvDfsM",
        "preferred_email": "myemail@example.com",
        "name": "My Partner Company",
        "sort_name": "My Partner Company",
        "type": "organization",
        "display_name": "My Partner Company"
    },
    "email_addresses": [
        {
            "id": "eml_mh5lADCijYgvLf5pMVvDl",
            "created": {
                "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
                "timestamp": "2018-06-07T16:22:17.446Z",
                "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
                "client_inet_address": "66.90.249.23",
                "client_country_code": "US",
                "client_location": "30.2414,-97.7687",
                "caller_inet_address": "66.90.249.23",
                "caller_country_code": "US",
                "caller_location": "30.2414,-97.7687"
            },
            "modified": {
                "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
                "timestamp": "2018-06-07T16:22:17.446Z",
                "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
                "client_inet_address": "66.90.249.23",
                "client_country_code": "US",
                "client_location": "30.2414,-97.7687",
                "caller_inet_address": "66.90.249.23",
                "caller_country_code": "US",
                "caller_location": "30.2414,-97.7687"
            },
            "address": "eripley@example.com",
            "preferred": false,
            "type": "email_address"
        }
    ],
    "first_name": "Ellen",
    "last_name": "Ripley",
    "display_name": "Ellen Ripley",
    "type": "person"
}

  

Get Contact by Source ID

GET /contacts/source-id?id={source_id}

Retrieves the specified Contact, using the specified source_id. The JSON for the Contact is returned, which does not include the source_id.

Query parameters
ParameterDescription
source_idThe caller-generated ID of the specified contact, which uniquely identifies a contact in the caller's environment. (required)
Search for contact by source ID
curl -X GET "Authorization: Bearer <access_token>" https://api.affinipay.com/contacts/source-id?id=MyPartner:contact-125
Example response
{
    "id": "p_tup7e7S0e7LIE55qvgXAR",
    "created": {
        "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
        "timestamp": "2018-06-07T16:22:17.445Z",
        "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
        "client_inet_address": "66.90.249.23",
        "client_country_code": "US",
        "client_location": "30.2414,-97.7687",
        "caller_inet_address": "66.90.249.23",
        "caller_country_code": "US",
        "caller_location": "30.2414,-97.7687"
    },
    "modified": {
        "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
        "timestamp": "2018-06-07T16:22:17.445Z",
        "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
        "client_inet_address": "66.90.249.23",
        "client_country_code": "US",
        "client_location": "30.2414,-97.7687",
        "caller_inet_address": "66.90.249.23",
        "caller_country_code": "US",
        "caller_location": "30.2414,-97.7687"
    },
    "test_mode": false,
    "name": "Ellen Ripley",
    "sort_name": "Ripley Ellen",
    "preferred_email": "eripley@example.com",
    "contact_code": "0010",
    "owner_id": "org_Y2eJHCXVqjMlXL9EfmBfc",
    "owner": {
        "id": "org_Y2eJHCXVqjMlXL9EfmBfc",
        "test_mode": false,
        "owner_id": "org_aQ5urhpA1HUBJIxAvDfsM",
        "preferred_email": "myemail@example.com",
        "name": "My Partner Company",
        "sort_name": "My Partner Company",
        "type": "organization",
        "display_name": "My Partner Company"
    },
    "email_addresses": [
        {
            "id": "eml_mh5lADCijYgvLf5pMVvDl",
            "created": {
                "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
                "timestamp": "2018-06-07T16:22:17.446Z",
                "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
                "client_inet_address": "66.90.249.23",
                "client_country_code": "US",
                "client_location": "30.2414,-97.7687",
                "caller_inet_address": "66.90.249.23",
                "caller_country_code": "US",
                "caller_location": "30.2414,-97.7687"
            },
            "modified": {
                "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
                "timestamp": "2018-06-07T16:22:17.446Z",
                "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
                "client_inet_address": "66.90.249.23",
                "client_country_code": "US",
                "client_location": "30.2414,-97.7687",
                "caller_inet_address": "66.90.249.23",
                "caller_country_code": "US",
                "caller_location": "30.2414,-97.7687"
            },
            "address": "eripley@example.com",
            "preferred": false,
            "type": "email_address"
        }
    ],
    "first_name": "Ellen",
    "last_name": "Ripley",
    "display_name": "Ellen Ripley",
    "type": "person"
}

  

Update Contact

PATCH /contacts/{contact_id}

Updates the specified Contact’s current parameter values with values that you provide. Any parameters that you do not specify in the PATCH will be left as-is.

Use this endpoint to:

  • Add an address, email, or phone number
  • Update an address, email, or phone number
  • Delete an address, email, or phone number
  • Update other contact parameters
URI parameters
ParameterDescription
contact_idThe system-generated ID of a specific contact. (ID prefix = org_or p_) (required)
Update name on contact
curl -X PATCH -H "Content-Type:application/json" "Authorization: Bearer <access_token>" https://api.affinipay.com/contacts/p_blM1oUmbCckoIdvoSstgS -d '
  {
    "last_name": "Lane"
  }'
Example response
{
    "id": "p_blM1oUmbCckoIdvoSstgS",
    "created": {
        "user": "admin@example.com",
        "timestamp": "2022-01-19T18:17:20.305Z",
        "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
        "client_inet_address": "97.65.251.242",
        "client_country_code": "US",
        "client_location": "30.2971,-97.7862",
        "caller_inet_address": "97.65.251.242",
        "caller_country_code": "US",
        "caller_location": "30.2971,-97.7862"
    },
    "modified": {
        "user": "admin@example.com",
        "timestamp": "2022-01-19T18:50:10.149Z",
        "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
        "client_inet_address": "97.65.251.242",
        "client_country_code": "US",
        "client_location": "30.2971,-97.7862",
        "caller_inet_address": "97.65.251.242",
        "caller_country_code": "US",
        "caller_location": "30.2971,-97.7862"
    },
    "test_mode": true,
    "name": "Clark Lane",
    "sort_name": "Lane Clark",
    "source_id": "partnername:1192022",
    "preferred_email": "ckent@example.com",
    "contact_code": "0031",
    "owner_id": "org_ayVmT9zfkH46buQT4HtBK",
    "owner": {
        "id": "org_ayVmT9zfkH46buQT4HtBK",
        "test_mode": false,
        "owner_id": "org_a9p7cYn9MzBIL6egPb51O",
        "preferred_email": "admin@example.com",
        "name": "Example Company",
        "sort_name": "Example Company",
        "type": "organization",
        "display_name": "Example Company"
    },
    "addresses": [
        {
            "id": "addr_qicRxmKYNEsDjLZEhlqE6",
            "created": {
                "user": "admin@example.com",
                "timestamp": "2022-01-19T18:36:20.874Z",
                "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
                "client_inet_address": "97.65.251.242",
                "client_country_code": "US",
                "client_location": "30.2971,-97.7862",
                "caller_inet_address": "97.65.251.242",
                "caller_country_code": "US",
                "caller_location": "30.2971,-97.7862"
            },
            "modified": {
                "user": "admin@example.com",
                "timestamp": "2022-01-19T18:36:20.874Z",
                "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
                "client_inet_address": "97.65.251.242",
                "client_country_code": "US",
                "client_location": "30.2971,-97.7862",
                "caller_inet_address": "97.65.251.242",
                "caller_country_code": "US",
                "caller_location": "30.2971,-97.7862"
            },
            "line1": "5400 Burnet",
            "city": "Austin",
            "state_or_province": "TX",
            "postal_code": "78756",
            "country_code": "US",
            "preferred": false,
            "type": "address"
        }
    ],
    "email_addresses": [
        {
            "id": "eml_Pocc0DLipfEZio0qA9f9p",
            "created": {
                "user": "admin@example.com",
                "timestamp": "2022-01-19T18:17:20.305Z",
                "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
                "client_inet_address": "97.65.251.242",
                "client_country_code": "US",
                "client_location": "30.2971,-97.7862",
                "caller_inet_address": "97.65.251.242",
                "caller_country_code": "US",
                "caller_location": "30.2971,-97.7862"
            },
            "modified": {
                "user": "admin@example.com",
                "timestamp": "2022-01-19T18:17:20.305Z",
                "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
                "client_inet_address": "97.65.251.242",
                "client_country_code": "US",
                "client_location": "30.2971,-97.7862",
                "caller_inet_address": "97.65.251.242",
                "caller_country_code": "US",
                "caller_location": "30.2971,-97.7862"
            },
            "address": "ckent@example.com",
            "preferred": true,
            "type": "email_address"
        }
    ],
    "first_name": "Clark",
    "last_name": "Lane",
    "display_name": "Clark Lane",
    "type": "person"
}

Add address to contact
curl -X PATCH -H "Content-Type:application/json" "Authorization: Bearer <access_token>" https://api.affinipay.com/contacts/p_blM1oUmbCckoIdvoSstgS -d '
{
    "addresses":[
        {
            "line1": "5400 Burnet",
            "city": "Austin",
            "state_or_province": "TX",
            "postal_code": "78756",
            "country_code": "US",
            "type": "address"
        }
    ]
}'
Example response
{
    "id": "p_blM1oUmbCckoIdvoSstgS",
    "created": {
        "user": "admin@example.com",
        "timestamp": "2022-01-19T18:17:20.305Z",
        "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
        "client_inet_address": "97.65.251.242",
        "client_country_code": "US",
        "client_location": "30.2971,-97.7862",
        "caller_inet_address": "97.65.251.242",
        "caller_country_code": "US",
        "caller_location": "30.2971,-97.7862"
    },
    "modified": {
        "user": "admin@example.com",
        "timestamp": "2022-01-19T18:36:20.876Z",
        "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
        "client_inet_address": "97.65.251.242",
        "client_country_code": "US",
        "client_location": "30.2971,-97.7862",
        "caller_inet_address": "97.65.251.242",
        "caller_country_code": "US",
        "caller_location": "30.2971,-97.7862"
    },
    "test_mode": true,
    "name": "Clark Kent",
    "sort_name": "Kent Clark",
    "source_id": "partnername:1192022",
    "preferred_email": "ckent@example.com",
    "contact_code": "0031",
    "owner_id": "org_ayVmT9zfkH46buQT4HtBK",
    "owner": {
        "id": "org_ayVmT9zfkH46buQT4HtBK",
        "test_mode": false,
        "owner_id": "org_a9p7cYn9MzBIL6egPb51O",
        "preferred_email": "admin@example.com",
        "name": "Example Company",
        "sort_name": "Example Company",
        "type": "organization",
        "display_name": "Example Company"
    },
    "addresses": [
        {
            "id": "addr_qicRxmKYNEsDjLZEhlqE6",
            "created": {
                "user": "admin@example.com",
                "timestamp": "2022-01-19T18:36:20.874Z",
                "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
                "client_inet_address": "97.65.251.242",
                "client_country_code": "US",
                "client_location": "30.2971,-97.7862",
                "caller_inet_address": "97.65.251.242",
                "caller_country_code": "US",
                "caller_location": "30.2971,-97.7862"
            },
            "modified": {
                "user": "admin@example.com",
                "timestamp": "2022-01-19T18:36:20.874Z",
                "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
                "client_inet_address": "97.65.251.242",
                "client_country_code": "US",
                "client_location": "30.2971,-97.7862",
                "caller_inet_address": "97.65.251.242",
                "caller_country_code": "US",
                "caller_location": "30.2971,-97.7862"
            },
            "line1": "5400 Burnet",
            "city": "Austin",
            "state_or_province": "TX",
            "postal_code": "78756",
            "country_code": "US",
            "preferred": false,
            "type": "address"
        }
    ],
    "email_addresses": [
        {
            "id": "eml_Pocc0DLipfEZio0qA9f9p",
            "created": {
                "user": "admin@example.com",
                "timestamp": "2022-01-19T18:17:20.305Z",
                "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
                "client_inet_address": "97.65.251.242",
                "client_country_code": "US",
                "client_location": "30.2971,-97.7862",
                "caller_inet_address": "97.65.251.242",
                "caller_country_code": "US",
                "caller_location": "30.2971,-97.7862"
            },
            "modified": {
                "user": "admin@example.com",
                "timestamp": "2022-01-19T18:17:20.305Z",
                "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
                "client_inet_address": "97.65.251.242",
                "client_country_code": "US",
                "client_location": "30.2971,-97.7862",
                "caller_inet_address": "97.65.251.242",
                "caller_country_code": "US",
                "caller_location": "30.2971,-97.7862"
            },
            "address": "ckent@example.com",
            "preferred": true,
            "type": "email_address"
        }
    ],
    "first_name": "Clark",
    "last_name": "Kent",
    "display_name": "Clark Kent",
    "type": "person"
}

  
Update email and set email to preferred
curl -X PATCH -H "Content-Type:application/json" "Authorization: Bearer <access_token>" https://api.affinipay.com/contacts/p_blM1oUmbCckoIdvoSstgS -d '
  {
    "email_addresses":[
        {
            "id": "eml_Pocc0DLipfEZio0qA9f9p",
            "address": "clane@example.com",
            "preferred": true
        }
    ]
}'
Example response
{
    "id": "p_blM1oUmbCckoIdvoSstgS",
    "created": {
        "user": "admin@example.com",
        "timestamp": "2022-01-19T18:17:20.305Z",
        "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
        "client_inet_address": "97.65.251.242",
        "client_country_code": "US",
        "client_location": "30.2971,-97.7862",
        "caller_inet_address": "97.65.251.242",
        "caller_country_code": "US",
        "caller_location": "30.2971,-97.7862"
    },
    "modified": {
        "user": "admin@example.com",
        "timestamp": "2022-01-19T18:53:17.980Z",
        "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
        "client_inet_address": "97.65.251.242",
        "client_country_code": "US",
        "client_location": "30.2971,-97.7862",
        "caller_inet_address": "97.65.251.242",
        "caller_country_code": "US",
        "caller_location": "30.2971,-97.7862"
    },
    "test_mode": true,
    "name": "Clark Lane",
    "sort_name": "Lane Clark",
    "source_id": "partnername:1192022",
    "preferred_email": "clane@example.com",
    "contact_code": "0031",
    "owner_id": "org_ayVmT9zfkH46buQT4HtBK",
    "owner": {
        "id": "org_ayVmT9zfkH46buQT4HtBK",
        "test_mode": false,
        "owner_id": "org_a9p7cYn9MzBIL6egPb51O",
        "preferred_email": "admin@example.com",
        "name": "Example Company",
        "sort_name": "Example Company",
        "type": "organization",
        "display_name": "Example Company"
    },
    "addresses": [
        {
            "id": "addr_qicRxmKYNEsDjLZEhlqE6",
            "created": {
                "user": "admin@example.com",
                "timestamp": "2022-01-19T18:36:20.874Z",
                "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
                "client_inet_address": "97.65.251.242",
                "client_country_code": "US",
                "client_location": "30.2971,-97.7862",
                "caller_inet_address": "97.65.251.242",
                "caller_country_code": "US",
                "caller_location": "30.2971,-97.7862"
            },
            "modified": {
                "user": "admin@example.com",
                "timestamp": "2022-01-19T18:36:20.874Z",
                "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
                "client_inet_address": "97.65.251.242",
                "client_country_code": "US",
                "client_location": "30.2971,-97.7862",
                "caller_inet_address": "97.65.251.242",
                "caller_country_code": "US",
                "caller_location": "30.2971,-97.7862"
            },
            "line1": "5400 Burnet",
            "city": "Austin",
            "state_or_province": "TX",
            "postal_code": "78756",
            "country_code": "US",
            "preferred": false,
            "type": "address"
        }
    ],
    "email_addresses": [
        {
            "id": "eml_Pocc0DLipfEZio0qA9f9p",
            "created": {
                "user": "admin@example.com",
                "timestamp": "2022-01-19T18:17:20.305Z",
                "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
                "client_inet_address": "97.65.251.242",
                "client_country_code": "US",
                "client_location": "30.2971,-97.7862",
                "caller_inet_address": "97.65.251.242",
                "caller_country_code": "US",
                "caller_location": "30.2971,-97.7862"
            },
            "modified": {
                "user": "admin@example.com",
                "timestamp": "2022-01-19T18:53:17.980Z",
                "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
                "client_inet_address": "97.65.251.242",
                "client_country_code": "US",
                "client_location": "30.2971,-97.7862",
                "caller_inet_address": "97.65.251.242",
                "caller_country_code": "US",
                "caller_location": "30.2971,-97.7862"
            },
            "address": "clane@example.com",
            "preferred": true,
            "type": "email_address"
        }
    ],
    "first_name": "Clark",
    "last_name": "Lane",
    "display_name": "Clark Lane",
    "type": "person"
}
    
Delete phone from contact
curl -X PATCH -H "Content-Type:application/json" "Authorization: Bearer <access_token>" https://api.affinipay.com/contacts/p_blM1oUmbCckoIdvoSstgS -d '
    {
      "phone_numbers": [
      {
            "id": "phn_ixjrK48Mes8TL1P7CDcFq"
      }
  ]
  }'
  
Example response
{
    "id": "p_blM1oUmbCckoIdvoSstgS",
    "created": {
        "user": "admin@example.com",
        "timestamp": "2022-01-19T18:17:20.305Z",
        "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
        "client_inet_address": "97.65.251.242",
        "client_country_code": "US",
        "client_location": "30.2971,-97.7862",
        "caller_inet_address": "97.65.251.242",
        "caller_country_code": "US",
        "caller_location": "30.2971,-97.7862"
    },
    "modified": {
        "user": "admin@example.com",
        "timestamp": "2022-01-19T18:55:51.432Z",
        "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
        "client_inet_address": "97.65.251.242",
        "client_country_code": "US",
        "client_location": "30.2971,-97.7862",
        "caller_inet_address": "97.65.251.242",
        "caller_country_code": "US",
        "caller_location": "30.2971,-97.7862"
    },
    "test_mode": true,
    "name": "Clark Lane",
    "sort_name": "Lane Clark",
    "source_id": "partnername:1192022",
    "preferred_email": "clane@example.com",
    "contact_code": "0031",
    "owner_id": "org_ayVmT9zfkH46buQT4HtBK",
    "owner": {
        "id": "org_ayVmT9zfkH46buQT4HtBK",
        "test_mode": false,
        "owner_id": "org_a9p7cYn9MzBIL6egPb51O",
        "preferred_email": "admin@example.com",
        "name": "Example Company",
        "sort_name": "Example Company",
        "type": "organization",
        "display_name": "Example Company"
    },
    "addresses": [
        {
            "id": "addr_qicRxmKYNEsDjLZEhlqE6",
            "created": {
                "user": "admin@example.com",
                "timestamp": "2022-01-19T18:36:20.874Z",
                "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
                "client_inet_address": "97.65.251.242",
                "client_country_code": "US",
                "client_location": "30.2971,-97.7862",
                "caller_inet_address": "97.65.251.242",
                "caller_country_code": "US",
                "caller_location": "30.2971,-97.7862"
            },
            "modified": {
                "user": "admin@example.com",
                "timestamp": "2022-01-19T18:36:20.874Z",
                "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
                "client_inet_address": "97.65.251.242",
                "client_country_code": "US",
                "client_location": "30.2971,-97.7862",
                "caller_inet_address": "97.65.251.242",
                "caller_country_code": "US",
                "caller_location": "30.2971,-97.7862"
            },
            "line1": "5400 Burnet",
            "city": "Austin",
            "state_or_province": "TX",
            "postal_code": "78756",
            "country_code": "US",
            "preferred": false,
            "type": "address"
        }
    ],
    "email_addresses": [
        {
            "id": "eml_Pocc0DLipfEZio0qA9f9p",
            "created": {
                "user": "admin@example.com",
                "timestamp": "2022-01-19T18:17:20.305Z",
                "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
                "client_inet_address": "97.65.251.242",
                "client_country_code": "US",
                "client_location": "30.2971,-97.7862",
                "caller_inet_address": "97.65.251.242",
                "caller_country_code": "US",
                "caller_location": "30.2971,-97.7862"
            },
            "modified": {
                "user": "admin@example.com",
                "timestamp": "2022-01-19T18:53:17.980Z",
                "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
                "client_inet_address": "97.65.251.242",
                "client_country_code": "US",
                "client_location": "30.2971,-97.7862",
                "caller_inet_address": "97.65.251.242",
                "caller_country_code": "US",
                "caller_location": "30.2971,-97.7862"
            },
            "address": "clane@example.com",
            "preferred": true,
            "type": "email_address"
        }
    ],
    "first_name": "Clark",
    "last_name": "Lane",
    "display_name": "Clark Lane",
    "type": "person"
}
    
      

Delete Contact

DELETE /contacts/{contact_id}

Deletes the specified Contact.

URI parameters
ParameterDescription
contact_idThe system-generated ID of a specific contact. (ID prefix = org_ or p_) (required)
Delete a Contact
curl -X DELETE "Content-Type:application/json" "Authorization: Bearer <access_token>" https://api.affinipay.com/contacts/p_AGx6xPaOQ9iLyjOHOYT5T
Example response
 {
    "id": "p_AGx6xPaOQ9iLyjOHOYT5T",
    "created": {
        "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
        "timestamp": "2018-02-14T22:14:30.256Z",
        "client_inet_address": "172.30.2.0",
        "caller_inet_address": "172.30.2.0"
    },
    "modified": {
        "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
        "timestamp": "2018-02-14T22:14:30.302Z",
        "client_inet_address": "172.30.2.0",
        "caller_inet_address": "172.30.2.0"
    },
    "test_mode": false,
    "name": "John Conner",
    "sort_name": "Conner John",
    "preferred_email": "jconner@example.com",
    "contact_code": "0438",
    "owner_id": "org_Y2eJHCXVqjMlXL9EfmBfc",
    "owner": {
        "id": "org_Y2eJHCXVqjMlXL9EfmBfc",
        "test_mode": false,
        "owner_id": "org_aQ5urhpA1HUBJIxAvDfsM",
        "preferred_email": "myemail@example.com",
        "name": "My Partner Company",
        "sort_name": "My Partner Company",
        "type": "organization",
        "display_name": "My Partner Company"
    },
    "email_addresses": [
        {
            "id": "eml_mh5lADCijYgvLf5pMVvDl",
            "created": {
                "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
                "timestamp": "2018-06-07T16:22:17.446Z",
                "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
                "client_inet_address": "66.90.249.23",
                "client_country_code": "US",
                "client_location": "30.2414,-97.7687",
                "caller_inet_address": "66.90.249.23",
                "caller_country_code": "US",
                "caller_location": "30.2414,-97.7687"
            },
            "modified": {
                "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
                "timestamp": "2018-06-07T16:22:17.446Z",
                "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
                "client_inet_address": "66.90.249.23",
                "client_country_code": "US",
                "client_location": "30.2414,-97.7687",
                "caller_inet_address": "66.90.249.23",
                "caller_country_code": "US",
                "caller_location": "30.2414,-97.7687"
            },
            "address": "jconner@example.com",
            "preferred": false,
            "type": "email_address"
        }
    ],
    "first_name": "John",
    "last_name": "Conner",
    "display_name": "John Conner",
    "type": "person"
}

  

Create Contact Hash

POST /contacts/{contact_id}/hash

Creates a ContactHash for the specified Contact. This includes a URL for the payment portal that is unique to the specified Contact. You can send this URL to the user so they can view and pay their Invoices.

The ContactHash expires after 90 days. If a user needs to access the URL after that point, you must create a new ContactHash. URI parameters
ParameterDescription
contact_idThe system-generated ID of a specific Contact. (ID prefix = ireq_) (required)
Get ContactHash
curl -X POST -H "Content-Type:application/json" "Authorization: Bearer <access_token>" https://api.affinipay.com/contacts/p_Igc4ScIpV9ofmd3VY4QZv/hash
Example response
{
    "hash": "20tf2dikjqngf1m1o8celuj3gan14dphaoonvb5tv4qs9se737dg",
    "url": "https://portal.affinipay.com/?c=20tf2dikjqngf1m1o8celuj3gan14dphaoonvb5tv4qs9se737dg,
    "contact_id": "p_Igc4ScIpV9ofmd3VY4QZv"
    }
  

Contact PaymentMethods

A PaymentMethod specifies payment details and is associated with a single Contact.

Before you begin, see the related developer documentation, which contains a list of all the steps required before you create a PaymentMethod.

Get PaymentMethods

GET /contacts/{contact_id}/payment-methods

Retrieves a list that includes each PaymentMethod for the specified Contact.

URI parameters
ParameterDescription
contact_idThe system-generated ID of a specific contact. (ID prefix = org_ or p_) (required)
Search for all PaymentMethods for a Contact
curl -X "Authorization: Bearer <access_token>" https://api.affinipay.com/contacts/p_E3ZUY3x1R87RISuzJ3vDm/payment-methods
Example response
[
    {
        "id": "pmtd_UlrciejZ4ZWpmOv8ldzM9",
        "created": {
            "user": “heather@example.com”,
            "timestamp": "2022-01-14T16:40:50.846Z",
            "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
            "client_inet_address": "97.65.251.242",
            "client_country_code": "US",
            "client_location": "30.2971,-97.7862",
            "caller_inet_address": "97.65.251.242",
            "caller_country_code": "US",
            "caller_location": "30.2971,-97.7862"
        },
        "modified": {
            "user": "heather@example.com",
            "timestamp": "2022-01-14T16:40:50.846Z",
            "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
            "client_inet_address": "97.65.251.242",
            "client_country_code": "US",
            "client_location": "30.2971,-97.7862",
            "caller_inet_address": "97.65.251.242",
            "caller_country_code": "US",
            "caller_location": "30.2971,-97.7862"
        },
        "payee_id": "org_ayVmT9zfkH46buQT4HtB",
        "address": {
            "line1": "111 New Street",
            "postal_code": "78756",
            "preferred": false,
            "type": "address"
        },
        "payment_type": "credit_card",
        "name": “Lu Harper”,
        "account_number": "************4242",
        "card_type": "VISA",
        "expiration_month": 10,
        "expiration_year": 2022,
        "preferred": false,
        "allow_future_payments": false,
        "test_mode": true,
        "authorized_uses": [
            "all"
        ],
        "type": "payment_method"
    },
    {
        "id": "pmtd_asVL25jmbbm6JFrjInZKC",
        "created": {
            "user": “heather@example.com”,
            "timestamp": "2022-01-14T16:37:48.431Z",
            "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
            "client_inet_address": "97.65.251.242",
            "client_country_code": "US",
            "client_location": "30.2971,-97.7862",
            "caller_inet_address": "97.65.251.242",
            "caller_country_code": "US",
            "caller_location": "30.2971,-97.7862"
        },
        "modified": {
            "user": "heather@example.com",
            "timestamp": "2022-01-14T16:37:48.431Z",
            "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
            "client_inet_address": "97.65.251.242",
            "client_country_code": "US",
            "client_location": "30.2971,-97.7862",
            "caller_inet_address": "97.65.251.242",
            "caller_country_code": "US",
            "caller_location": "30.2971,-97.7862"
        },
        "payee_id": "org_ayVmT9zfkH46buQT4HtB",
        "address": {
            "line1": "111 New Street",
            "postal_code": "78756",
            "preferred": false,
            "type": "address"
        },
        "payment_type": "credit_card",
        "name": “Lu Harper”,
        "account_number": “************1234”,
        "card_type": "VISA",
        "expiration_month": 11,
        "expiration_year": 2024,
        "preferred": false,
        "allow_future_payments": false,
        "test_mode": true,
        "authorized_uses": [
            "all"
        ],
        "type": "payment_method"
    }
]

  

Create PaymentMethod

POST /contacts/{contact_id}/payment-methods

Before you begin, see the related developer documentation, which contains a list of all the steps required before you create a PaymentMethod.

Creates a PaymentMethod associated with the specified Contact.

To display in AffiniPay's Card Vault, the PaymentMethod's Contact must have the tag: default. URI parameters
ParameterDescription
contact_idThe system-generated ID of a specific Contact. (ID prefix = p_ or org_) (required)
Create payment method that can be used by merchant or client
curl -X POST -H "Content-Type:application/json" "Authorization: Bearer <access_token>" https://api.affinipay.com/contacts/org_Y2eJHCXVqjMlXL9EfmBfc/payment-methods -d '
  {
  "payment_type": "credit_card",
  "one_time_token": "zGOEGW9aTvmOEruuX2UGHw",
  "authorized_uses":["all"]
  }'
Example response
{
    "id": "pmtd_WesqHDqMXBn1RoI6qDTOu",
    "created": {
        "user": "eripley@example.com",
        "timestamp": "2020-12-07T19:46:42.149Z",
        "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
        "client_inet_address": "66.90.249.23",
        "client_country_code": "US",
        "client_location": "30.2971,-97.8181",
        "caller_inet_address": "66.90.249.23",
        "caller_country_code": "US",
        "caller_location": "30.2971,-97.8181"
    },
    "modified": {
        "user": "eripley@example.com",
        "timestamp": "2020-12-07T19:46:42.149Z",
        "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
        "client_inet_address": "66.90.249.23",
        "client_country_code": "US",
        "client_location": "30.2971,-97.8181",
        "caller_inet_address": "66.90.249.23",
        "caller_country_code": "US",
        "caller_location": "30.2971,-97.8181"
    },
    "payee_id": "org_Y2eJHCXVqjMlXL9EfmBfc",
    "address": {
        "line1": "123 Street St",
        "postal_code": "78701",
        "preferred": false,
        "type": "address"
    },
    "payment_type": "credit_card",
    "name": "Some Customer",
    "account_number": "************4242",
    "card_type": "VISA",
    "expiration_month": 10,
    "expiration_year": 2025,
    "preferred": false,
    "allow_future_payments": false,
    "test_mode": false,
    "authorized_uses": [
        "all"
    ],
    "type": "payment_method"
}
  

Get PaymentMethod

GET /contacts/{contact_id}/payment-methods/{payment_method_id}

Retrieves the specified PaymentMethod for the specified contact.

URI parameters
ParameterDescription
contact_idThe system-generated ID of a specific Contact. (ID prefix = p_ or org_) (required)
payment_method_idThe system-generated ID of a specific PaymentMethod. (ID prefix = pmtd_) (required)
Search for a PaymentMethod for a Contact
curl -X GET "Authorization: Bearer <access_token>" https://api.affinipay.com/contacts/p_ICBy63BhpJOGzEPpv1Wp0/payment-methods/pmtd_UlrciejZ4ZWpmOv8ldzM9
Example response
{
    "id": "pmtd_UlrciejZ4ZWpmOv8ldzM9",
    "created": {
        "user": “admin@example.com",
        "timestamp": "2022-01-14T16:40:50.846Z",
        "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
        "client_inet_address": "97.65.251.242",
        "client_country_code": "US",
        "client_location": "30.2971,-97.7862",
        "caller_inet_address": "97.65.251.242",
        "caller_country_code": "US",
        "caller_location": "30.2971,-97.7862"
    },
    "modified": {
        "user": “admin@example.com",
        "timestamp": "2022-01-14T16:40:50.846Z",
        "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
        "client_inet_address": "97.65.251.242",
        "client_country_code": "US",
        "client_location": "30.2971,-97.7862",
        "caller_inet_address": "97.65.251.242",
        "caller_country_code": "US",
        "caller_location": "30.2971,-97.7862"
    },
    "payee_id": "org_ayVmT9zfkH46buQT4HtBK",
    "address": {
        "line1": "111 New Street",
        "postal_code": "78756",
        "preferred": false,
        "type": "address"
    },
    "payment_type": "credit_card",
    "name": “Peter Parker,
    "account_number": "************4242",
    "card_type": "VISA",
    "expiration_month": 10,
    "expiration_year": 2026,
    "preferred": false,
    "allow_future_payments": false,
    "test_mode": true,
    "authorized_uses": [
        "all"
    ],
    "type": "payment_method"
}

  

Update PaymentMethod

PATCH /contacts/{contact_id}/payment-methods/{payment_method_id}

Updates the specified PaymentMethod.

URI parameters
ParameterDescription
contact_idThe system-generated ID of a specific Contact. (ID prefix = p_ or org_) (required)
payment_method_idThe system-generated ID of a specific PaymentMethod. (ID prefix = pmtd_) (required)
Update PaymentMethod
curl -X PATCH -H "Content-Type:application/json" "Authorization: Bearer <access_token>" https://api.affinipay.com/contacts/org_Y2eJHCXVqjMlXL9EfmBfc/payment-methods/pmtd_WesqHDqMXBn1RoI6qDTOu -d '
  {
  "one_time_token": "HEXXpttNSHyK6U0nH3DxEQ"
  }'
Example response
{
    "id": "pmtd_WesqHDqMXBn1RoI6qDTOu",
    "created": {
        "user": "eripley@example.com",
        "timestamp": "2020-12-08T19:46:42.149Z",
        "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
        "client_inet_address": "66.90.249.23",
        "client_country_code": "US",
        "client_location": "30.2971,-97.8181",
        "caller_inet_address": "66.90.249.23",
        "caller_country_code": "US",
        "caller_location": "30.2971,-97.8181"
    },
    "modified": {
        "user": "eripley@example.com",
        "timestamp": "2020-12-08T19:46:42.149Z",
        "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
        "client_inet_address": "66.90.249.23",
        "client_country_code": "US",
        "client_location": "30.2971,-97.8181",
        "caller_inet_address": "66.90.249.23",
        "caller_country_code": "US",
        "caller_location": "30.2971,-97.8181"
    },
    "payee_id": "org_Y2eJHCXVqjMlXL9EfmBfc",
    "address": {
        "line1": "123 Street St",
        "postal_code": "78701",
        "preferred": false,
        "type": "address"
    },
    "payment_type": "credit_card",
    "name": "Some Customer",
    "account_number": "************4242",
    "card_type": "VISA",
    "expiration_month": 04,
    "expiration_year": 2030,
    "preferred": false,
    "allow_future_payments": false,
    "test_mode": false,
    "authorized_uses": [
        "all"
    ],
    "type": "payment_method"
}
  

Delete PaymentMethod

DELETE /contacts/{contact_id}/payment-methods/{payment_method_id}

Deletes the specified PaymentMethod.

URI parameters
ParameterDescription
contact_idThe system-generated ID of a specific Contact. (ID prefix = p_ or org_) (required)
payment_method_idThe system-generated ID of a specific PaymentMethod. (ID prefix = pmtd_) (required)
Delete a payment method
curl -X POST "Content-Type:application/json" "Authorization: Bearer <access_token>" https://api.affinipay.com/contacts/org_Y2eJHCXVqjMlXL9EfmBfc/payment-methods/pmtd_WesqHDqMXBn1RoI6qDTOu
Example response
{
    "id": "pmtd_WesqHDqMXBn1RoI6qDTOu",
    "created": {
        "user": "eripley@example.com",
        "timestamp": "2020-12-07T19:46:42.149Z",
        "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
        "client_inet_address": "66.90.249.23",
        "client_country_code": "US",
        "client_location": "30.2971,-97.8181",
        "caller_inet_address": "66.90.249.23",
        "caller_country_code": "US",
        "caller_location": "30.2971,-97.8181"
    },
    "modified": {
        "user": "eripley@example.com",
        "timestamp": "2020-12-07T19:46:42.149Z",
        "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
        "client_inet_address": "66.90.249.23",
        "client_country_code": "US",
        "client_location": "30.2971,-97.8181",
        "caller_inet_address": "66.90.249.23",
        "caller_country_code": "US",
        "caller_location": "30.2971,-97.8181"
    },
    "payee_id": "org_Y2eJHCXVqjMlXL9EfmBfc",
    "address": {
        "line1": "123 Street St",
        "postal_code": "78701",
        "preferred": false,
        "type": "address"
    },
    "payment_type": "credit_card",
    "name": "Some Customer",
    "account_number": "************4242",
    "card_type": "VISA",
    "expiration_month": 10,
    "expiration_year": 2025,
    "preferred": false,
    "allow_future_payments": false,
    "test_mode": false,
    "authorized_uses": [
        "all"
    ],
    "type": "payment_method"
}
  

File Uploads for Attachments

Before you can attach a file to an Invoice, you must upload it. These uploaded files are associated with a particular Contact: the merchant that owns the file.

Introspect Token

POST /oauth/introspect

Retrieves information about the OAuth token provided in the request. This includes the merchant_id (the contact_id for the merchant user), which is required for managing attachments.

Introspect the OAuth token
curl POST "content-type: application/x-www-form-urlencoded " "data-urlencode: token=144e6bc3c493f75c70626d8b03ce192dd5898c89ecbdfc7e98d925948a63d9ae2''" "Authorization: Bearer <access_token>" https://api.affinipay.com/oauth/introspect'
Example response
{
    "active": true,
    "client_id": “41a2c10139e63db49b0efe23b16fea19c685d7c896657470174a1c9c91b54cddk7”,
    "username": “pparker@example.com",
    "scope": "payments",
    "exp": null,
    "iat": 1758326109523,
    "principal": {
        "merchant_id": "org_ayVmT89zfkH46buQYT4HtBK",
        "merchant_name": “Parker and Parker“,
        "email": “pparker@example.com",
        "gateway_public_key": “m_cSiyNLUh92RBWHfdbFRFGrkA”,
        "country": "US",
        "default_currency": "USD",
        "services": [],
        "first_name": “Peter”,
        "last_name": “Parker”,
        "mobile_number": null
    }
}
  

Get Uploaded Files

GET /contacts/{contact_id}/attachments

Retrieves a list of uploaded files that can be attached to an invoice. After a file has been attached to an invoice, information about it can no longer be retrieved using this endpoint; instead, you must view the Invoice.

URI parameters
ParameterDescription
contact_idThe system-generated ID of an organization; in this case, this is the merchant that owns the attachment. (ID prefix = org_) (required)
View all uploaded, unattached files for a merchant
curl -X GET "Authorization: Bearer <access_token>" https://api.affinipay.com/contacts/org_Y2eJHCXVqjMlXL9EfmBfc/attachments
Example response
[
    {
        "id": "fref_2lF7xITE97IXZe6jIQkqp",
        "created": {
            "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
            "timestamp": "2018-09-28T18:02:57.553Z",
            "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
            "client_inet_address": "66.90.249.23",
            "client_country_code": "US",
            "client_location": "30.2961,-97.7369",
            "caller_inet_address": "66.90.249.23",
            "caller_country_code": "US",
            "caller_location": "30.2961,-97.7369"
        },
        "modified": {
            "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
            "timestamp": "2018-09-28T18:02:57.592Z",
            "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
            "client_inet_address": "66.90.249.23",
            "client_country_code": "US",
            "client_location": "30.2961,-97.7369",
            "caller_inet_address": "66.90.249.23",
            "caller_country_code": "US",
            "caller_location": "30.2961,-97.7369"
        },
        "file_name": "invoice123456789.pdf",
        "processing_state": "completed",
        "type": "invoice_file_reference"
    },
    {
        "id": "fref_Zp1sporjFUcg9mmWsgRbu",
        "created": {
            "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
            "timestamp": "2018-09-28T18:03:41.579Z",
            "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
            "client_inet_address": "66.90.249.23",
            "client_country_code": "US",
            "client_location": "30.2961,-97.7369",
            "caller_inet_address": "66.90.249.23",
            "caller_country_code": "US",
            "caller_location": "30.2961,-97.7369"
        },
        "modified": {
            "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
            "timestamp": "2018-09-28T18:03:41.694Z",
            "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
            "client_inet_address": "66.90.249.23",
            "client_country_code": "US",
            "client_location": "30.2961,-97.7369",
            "caller_inet_address": "66.90.249.23",
            "caller_country_code": "US",
            "caller_location": "30.2961,-97.7369"
        },
        "file_name": "invoice123456788.pdf",
        "processing_state": "completed",
        "type": "invoice_file_reference"
    }
]

  

Upload Files to be Attached

POST /contacts/{contact_id}/attachments

Uploads one or more files, which can then be attached to an invoice. Each merchant can have up to 10MB of unattached uploaded files. The following types of files can be uploaded and attached:

  • PDF
  • Documents/text: Word (DOC, DOCX), TXT, RTF
  • Spreadsheets: Excel (XLS, XLSX), CSV
  • Images: JPG, PNG, TIF, GIF

An unattached uploaded file is kept in the system for 24 hours. After a file is attached to an invoice, it's available until the invoice is paid.

URI parameters
ParameterDescription
contact_idThe system-generated ID of an organization; in this case, this is the merchant that owns the attachment. (ID prefix = org_) (required)
Upload a PDF file
curl -X POST -H "content-type: multipart/form-data" -F file=invoice123456789.pdf "Authorization: Bearer <access_token>" https://api.affinipay.com/contacts/org_Y2eJHCXVqjMlXL9EfmBfc/attachments
Example response
{
    "id": "fref_B1uzo7pWYndwlbbyRbuEX",
    "created": {
        "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
        "timestamp": "2018-09-28T17:26:03.506Z",
        "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
        "client_inet_address": "66.90.249.23",
        "client_country_code": "US",
        "client_location": "30.2961,-97.7369",
        "caller_inet_address": "66.90.249.23",
        "caller_country_code": "US",
        "caller_location": "30.2961,-97.7369"
    },
    "modified": {
        "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
        "timestamp": "2018-09-28T17:26:03.506Z",
        "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
        "client_inet_address": "66.90.249.23",
        "client_country_code": "US",
        "client_location": "30.2961,-97.7369",
        "caller_inet_address": "66.90.249.23",
        "caller_country_code": "US",
        "caller_location": "30.2961,-97.7369"
    },
    "file_name": "invoice123456789.pdf",
    "processing_state": "processing",
    "type": "invoice_file_reference"
  }
  

View Uploaded File Status

GET /contacts/{contact_id}/attachments/{attachment_id}

Retrieves details about an uploaded file, before it is attached to an invoice. Use this endpoint to verify that an upload is complete.

An uploaded file can be in one of the following processing states:

  • processing. The attachment/file is being scanned.
  • completed. The attachment/file has been scanned successfully.
  • failed. The attachment/file has been flagged as dangerous and will be purged from the system.

After a file has been attached to an invoice, information about it can no longer be retrieved using this endpoint; instead, you must view the Invoice.

URI parameters
ParameterDescription
contact_idThe system-generated ID of an organization; in this case, this is the merchant that owns the attachment. (ID prefix = org_) (required)
attachment_idThe system-generated ID of an uploaded file (ID prefix = fref_) (required)
Check the upload status
curl -X GET "Authorization: Bearer <access_token>" https://api.affinipay.com/contacts/org_Y2eJHCXVqjMlXL9EfmBfc/attachments/fref_uJ2CAdyGNdPZzuSJDFsqe
Example response
{
    "id": "fref_uJ2CAdyGNdPZzuSJDFsqe",
    "created": {
        "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
        "timestamp": "2018-09-28T20:20:21.587Z",
        "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
        "client_inet_address": "66.90.249.23",
        "client_country_code": "US",
        "client_location": "30.2961,-97.7369",
        "caller_inet_address": "66.90.249.23",
        "caller_country_code": "US",
        "caller_location": "30.2961,-97.7369"
    },
    "modified": {
        "user": "SERVER",
        "timestamp": "2018-09-28T20:20:26.589Z",
        "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
        "client_inet_address": "0.0.0.0",
        "client_country_code": "US",
        "client_location": "30.2961,-97.7369",
        "caller_inet_address": "0.0.0.0",
        "caller_country_code": "US",
        "caller_location": "30.2961,-97.7369"
    },
    "file_name": "invoice123456787.pdf",
    "processing_state": "completed",
    "type": "invoice_file_reference"
}

  

Delete Uploaded File

DELETE /contacts/{contact_id}/attachments/{attachment_id}

Deletes the specified uploaded file. After a file has been attached to an invoice, it can no longer be deleted using this endpoint.

URI parameters
ParameterDescription
contact_idThe system-generated ID of an organization; in this case, this is the merchant that owns the attachment. (ID prefix = org_) (required)
attachment_idThe system-generated ID of an uploaded file (ID prefix = fref_) (required)
Delete an uploaded file
curl -X DELETE "Authorization: Bearer <access_token>" https://api.affinipay.com/contacts/org_Y2eJHCXVqjMlXL9EfmBfc/attachments/fref_uJ2CAdyGNdPZzuSJDFsqe
Example response
{
    "id": "fref_uJ2CAdyGNdPZzuSJDFsqe",
    "created": {
        "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
        "timestamp": "2018-09-28T20:20:21.587Z",
        "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
        "client_inet_address": "66.90.249.23",
        "client_country_code": "US",
        "client_location": "30.2961,-97.7369",
        "caller_inet_address": "66.90.249.23",
        "caller_country_code": "US",
        "caller_location": "30.2961,-97.7369"
    },
    "modified": {
        "user": "SERVER",
        "timestamp": "2018-09-28T20:20:26.589Z",
        "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
        "client_inet_address": "0.0.0.0",
        "client_country_code": "US",
        "client_location": "30.2961,-97.7369",
        "caller_inet_address": "0.0.0.0",
        "caller_country_code": "US",
        "caller_location": "30.2961,-97.7369"
    },
    "file_name": "invoice123456787.pdf",
    "processing_state": "completed",
    "type": "invoice_file_reference"
}

  

InfoRequests

An InfoRequest enables you to request that a Contact save their own payment method for future charges.

Before you begin, see the related developer documentation, which contains a list of all the steps required before you create an InfoRequest.

Search InfoRequests

GET /contacts/info-requests

Retrieves a list that contains each InfoRequest.

Query parameters

ParameterTypeDescription
order_byArray of StringThe list of fields to sort by, prefixed with - for descending. To include multiple fields, separate them with a comma. For example, order_by=field1,-field2. (optional)
pageInt32The page number, starting at 1. The default value is 1. (optional)
page_sizeInt32The maximum number of items in the page. (optional)
Search for all InfoRequests
curl -X GET "Authorization: Bearer <access_token>" https://api.affinipay.com/contacts/info-requests/
Example response
{
    "page": 1,
    "page_size": 20,
    "total_entries": 4,
    "results": [
    {
       "id": "ireq_VMV2xYvse0n7mm9TAtNL1",
       "created": {
           "user": "arden@example.com",
           "timestamp": "2021-09-13T18:00:09.683Z",
           "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
           "client_inet_address": "97.65.251.242",
           "client_country_code": "US",
           "client_location": "30.3773,-97.71",
           "caller_inet_address": "97.65.251.242",
           "caller_country_code": "US",
           "caller_location": "30.3773,-97.71"
       },
       "modified": {
           "user": "arden@example.com",
           "timestamp": "2021-09-13T18:00:09.683Z",
           "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
           "client_inet_address": "97.65.251.242",
           "client_country_code": "US",
           "client_location": "30.3773,-97.71",
           "caller_inet_address": "97.65.251.242",
           "caller_country_code": "US",
           "caller_location": "30.3773,-97.71"
       },
       "owner_id": "org_ayVmT9zfkH46buQT4HtBK",
       "contact_id": "p_Igc4ScIpV9ofmd3VY4QZv",
       "test_mode": true,
       "status": "pending",
       "message": {
           "subject": "Please provide your payment information",
           "body": "Please provide your payment information so we can start our working relationship. This information will be stored securely and we will not make any charges without informing you first."
       },
       "type": "payment_info_request"
       },
       {
            "id": "ireq_qOhyydckV3HgKBuKWKNv5",
            "created": {
                "user": "arden@example.com",
                "timestamp": "2021-09-08T14:16:15.479Z",
                "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
                "client_inet_address": "65.36.124.174",
                "client_country_code": "US",
                "client_location": "30.3643,-97.6864",
                "caller_inet_address": "65.36.124.174",
                "caller_country_code": "US",
                "caller_location": "30.3643,-97.6864"
            },
            "modified": {
                "user": "arden@example.com",
                "timestamp": "2021-09-08T14:16:15.479Z",
                "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
                "client_inet_address": "65.36.124.174",
                "client_country_code": "US",
                "client_location": "30.3643,-97.6864",
                "caller_inet_address": "65.36.124.174",
                "caller_country_code": "US",
                "caller_location": "30.3643,-97.6864"
            },
            "owner_id": "org_ayVmT9zfkH46buQT4HtBK",
            "contact_id": "p_ICBy63BhpJOGzEPpv1Wp0",
            "status": "pending",
            "message": {
                "subject": "Please provide your payment information",
                "body": "Please provide your payment information so we can start our working relationship. This information will be stored securely and we will not make any charges without informing you first."
            },
            "type": "payment_info_request"
        },
        {
            "id": "ireq_CGGkI0ovoglyFLadQU5fV",
            "created": {
                "user": "arden@example.com",
                "timestamp": "2021-09-08T13:38:34.383Z",
                "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
                "client_inet_address": "65.36.124.174",
                "client_country_code": "US",
                "client_location": "30.3643,-97.6864",
                "caller_inet_address": "65.36.124.174",
                "caller_country_code": "US",
                "caller_location": "30.3643,-97.6864"
            },
            "modified": {
                "user": "arden@example.com",
                "timestamp": "2021-09-08T16:42:54.775Z",
                "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
                "client_inet_address": "65.36.124.174",
                "client_country_code": "US",
                "client_location": "30.3643,-97.6864",
                "caller_inet_address": "65.36.124.174",
                "caller_country_code": "US",
                "caller_location": "30.3643,-97.6864"
            },
            "owner_id": "org_ayVmT9zfkH46buQT4HtBK",
            "contact_id": "p_ICBy63BhpJOGzEPpv1Wp0",
            "status": "canceled",
            "message": {
                "subject": "Please provide your payment information",
                "body": "Please provide your payment information so we can start our working relationship. This information will be stored securely and we will not make any charges without informing you first."
            },
            "type": "payment_info_request"
        },
        {
            "id": "ireq_dIj692hiqtMEwELSPRWvQ",
            "created": {
                "user": "arden@example.com",
                "timestamp": "2021-09-08T13:17:43.975Z",
                "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
                "client_inet_address": "65.36.124.174",
                "client_country_code": "US",
                "client_location": "30.3643,-97.6864",
                "caller_inet_address": "65.36.124.174",
                "caller_country_code": "US",
                "caller_location": "30.3643,-97.6864"
            },
            "modified": {
                "user": "ANONYMOUS",
                "timestamp": "2021-09-08T13:23:48.854Z",
                "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
                "client_inet_address": "65.36.124.174",
                "client_country_code": "US",
                "client_location": "30.3643,-97.6864",
                "caller_inet_address": "65.36.124.174",
                "caller_country_code": "US",
                "caller_location": "30.3643,-97.6864"
            },
            "owner_id": "org_ayVmT9zfkH46buQT4HtBK",
            "payment_method_id": "pmtd_XnaSTWOhr5dy1Dg3mcD6M",
            "contact_id": "p_ICBy63BhpJOGzEPpv1Wp0",
            "status": "completed",
            "message": {
                "subject": "Please provide your payment information",
                "body": "Please provide your payment information so we can start our working relationship. This information will be stored securely and we will not make any charges without informing you first."
            },
            "type": "payment_info_request"
        }
    ]
}

  

Get InfoRequests for Contact

GET /contacts/{contact_id}/info-requests

Retrieves a list that contains each InfoRequest for the specified contact.

URI parameters
ParameterDescription
contact_idThe system-generated ID of a specific Contact. (ID prefix = p_ or org_) (required)

Query parameters

ParameterTypeDescription
order_byArray of StringThe list of fields to sort by, prefixed with - for descending. To include multiple fields, separate them with a comma. For example, order_by=field1,-field2. (optional)
pageInt32The page number, starting at 1. The default value is 1. (optional)
page_sizeInt32The maximum number of items in the page. (optional)
Search for all InfoRequests for Contact
curl -X GET "Authorization: Bearer <access_token>" https://api.affinipay.com/contacts/p_ICBy63BhpJOGzEPpv1Wp0/info-requests/
Example response
{
    "page": 1,
    "page_size": 20,
    "total_entries": 3,
    "results": [
        {
            "id": "ireq_qOhyydckV3HgKBuKWKNv5",
            "created": {
                "user": "arden@example.com",
                "timestamp": "2021-09-08T14:16:15.479Z",
                "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
                "client_inet_address": "65.36.124.174",
                "client_country_code": "US",
                "client_location": "30.3643,-97.6864",
                "caller_inet_address": "65.36.124.174",
                "caller_country_code": "US",
                "caller_location": "30.3643,-97.6864"
            },
            "modified": {
                "user": "arden@example.com",
                "timestamp": "2021-09-08T14:16:15.479Z",
                "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
                "client_inet_address": "65.36.124.174",
                "client_country_code": "US",
                "client_location": "30.3643,-97.6864",
                "caller_inet_address": "65.36.124.174",
                "caller_country_code": "US",
                "caller_location": "30.3643,-97.6864"
            },
            "owner_id": "org_ayVmT9zfkH46buQT4HtBK",
            "contact_id": "p_ICBy63BhpJOGzEPpv1Wp0",
            "status": "pending",
            "message": {
                "subject": "Please provide your payment information",
                "body": "Please provide your payment information so we can start our working relationship. This information will be stored securely and we will not make any charges without informing you first."
            },
            "type": "payment_info_request"
        },
        {
            "id": "ireq_CGGkI0ovoglyFLadQU5fV",
            "created": {
                "user": "arden@example.com",
                "timestamp": "2021-09-08T13:38:34.383Z",
                "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
                "client_inet_address": "65.36.124.174",
                "client_country_code": "US",
                "client_location": "30.3643,-97.6864",
                "caller_inet_address": "65.36.124.174",
                "caller_country_code": "US",
                "caller_location": "30.3643,-97.6864"
            },
            "modified": {
                "user": "arden@example.com",
                "timestamp": "2021-09-08T16:42:54.775Z",
                "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
                "client_inet_address": "65.36.124.174",
                "client_country_code": "US",
                "client_location": "30.3643,-97.6864",
                "caller_inet_address": "65.36.124.174",
                "caller_country_code": "US",
                "caller_location": "30.3643,-97.6864"
            },
            "owner_id": "org_ayVmT9zfkH46buQT4HtBK",
            "contact_id": "p_ICBy63BhpJOGzEPpv1Wp0",
            "status": "canceled",
            "message": {
                "subject": "Please provide your payment information",
                "body": "Please provide your payment information so we can start our working relationship. This information will be stored securely and we will not make any charges without informing you first."
            },
            "type": "payment_info_request"
        },
        {
            "id": "ireq_dIj692hiqtMEwELSPRWvQ",
            "created": {
                "user": "arden@example.com",
                "timestamp": "2021-09-08T13:17:43.975Z",
                "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
                "client_inet_address": "65.36.124.174",
                "client_country_code": "US",
                "client_location": "30.3643,-97.6864",
                "caller_inet_address": "65.36.124.174",
                "caller_country_code": "US",
                "caller_location": "30.3643,-97.6864"
            },
            "modified": {
                "user": "ANONYMOUS",
                "timestamp": "2021-09-08T13:23:48.854Z",
                "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
                "client_inet_address": "65.36.124.174",
                "client_country_code": "US",
                "client_location": "30.3643,-97.6864",
                "caller_inet_address": "65.36.124.174",
                "caller_country_code": "US",
                "caller_location": "30.3643,-97.6864"
            },
            "owner_id": "org_ayVmT9zfkH46buQT4HtBK",
            "payment_method_id": "pmtd_XnaSTWOhr5dy1Dg3mcD6M",
            "contact_id": "p_ICBy63BhpJOGzEPpv1Wp0",
            "status": "completed",
            "message": {
                "subject": "Please provide your payment information",
                "body": "Please provide your payment information so we can start our working relationship. This information will be stored securely and we will not make any charges without informing you first."
            },
            "type": "payment_info_request"
        }
    ]
}

  

Create InfoRequest

POST /contacts/info-requests

Creates an InfoRequest for the Contact specified in the request body. The InfoRequest, sent via a link to our portal, can be sent to the Contact:

  • By AffiniPay
    • Ensure the Contact has at least one email address defined. This determines the address to which the request will be sent.
    • Ensure the Contact has one tag defined: default. This ensures that when the new payment method is saved, it is available within the AffiniPay Card Vault.
    • Include the message parameter. To use the merchant's default email subject and body, use empty strings for these values; otherwise, provide a custom subject and body for the email.
  • By You
    • Ensure the Contact has one tag defined: default. This ensures that when the new payment method is saved, it is available within the AffiniPay Card Vault.
    • Retrieve the url from the InfoRequestHash, which is a link to the page in the AffiniPay portal where they can submit their payment method.
    • Send the Contact the link to the portal.

Upon successful submission by the Contact in the payment portal, these details are saved as a PaymentMethod and can be used for future transactions.

Create InfoRequest and AffiniPay will send link to Contact in default email
curl -X POST -H "Content-Type:application/json" "Authorization: Bearer <access_token>" https://api.affinipay.com/contacts/info-requests -d '
  {
      "contact_id": "p_ICBy63BhpJOGzEPpv1Wp0",
      "message": {
        "subject": "",
        "body": ""
      }
  }'
Example response
{
      "id": "ireq_SxPwrMuqAlPIPCFf4M40k",
      "created": {
          "user": "arden@example.com",
          "timestamp": "2021-09-07T22:33:36.767Z",
          "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
          "client_inet_address": "65.36.124.174",
          "client_country_code": "US",
          "client_location": "30.3643,-97.6864",
          "caller_inet_address": "65.36.124.174",
          "caller_country_code": "US",
          "caller_location": "30.3643,-97.6864"
      },
      "modified": {
          "user": "arden@example.com",
          "timestamp": "2021-09-07T22:33:36.767Z",
          "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
          "client_inet_address": "65.36.124.174",
          "client_country_code": "US",
          "client_location": "30.3643,-97.6864",
          "caller_inet_address": "65.36.124.174",
          "caller_country_code": "US",
          "caller_location": "30.3643,-97.6864"
      },
      "owner_id": "org_ayVmT9zfkH46buQT4HtBK",
      "contact_id": "p_ICBy63BhpJOGzEPpv1Wp0",
      "status": "pending",
      "message": {
        "subject": "Please Provide Your Payment Information",
        "body": "In order to provide the services you are requesting, we need you to provide your payment information. All information you provide us will be safely stored, and no charges will be made without notifying you of any anticipated charge."
        },
      "type": "payment_info_request"
  }
Create InfoRequest and AffiniPay will send link to Contact in custom email
curl -X POST -H "Content-Type:application/json" "Authorization: Bearer <access_token>" https://api.affinipay.com/contacts/info-requests -d '
  {
      "contact_id": "p_ICBy63BhpJOGzEPpv1Wp0",
      "message": {
        "subject": "Please provide your payment information",
        "body": "Please provide your payment information so we can start our working relationship. This information will be stored securely and we will not make any charges without informing you first."
      }
  }'
Example response
{
      "id": "ireq_SxPwrMuqAlPIPCFf4M40k",
      "created": {
          "user": "arden@example.com",
          "timestamp": "2021-09-07T22:33:36.767Z",
          "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
          "client_inet_address": "65.36.124.174",
          "client_country_code": "US",
          "client_location": "30.3643,-97.6864",
          "caller_inet_address": "65.36.124.174",
          "caller_country_code": "US",
          "caller_location": "30.3643,-97.6864"
      },
      "modified": {
          "user": "arden@example.com",
          "timestamp": "2021-09-07T22:33:36.767Z",
          "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
          "client_inet_address": "65.36.124.174",
          "client_country_code": "US",
          "client_location": "30.3643,-97.6864",
          "caller_inet_address": "65.36.124.174",
          "caller_country_code": "US",
          "caller_location": "30.3643,-97.6864"
      },
      "owner_id": "org_ayVmT9zfkH46buQT4HtBK",
      "contact_id": "p_ICBy63BhpJOGzEPpv1Wp0",
      "status": "pending",
      "message": {
        "subject": "Please provide your payment information",
        "body": "Please provide your payment information so we can start our working relationship. This information will be stored securely and we will not make any charges without informing you first."
        },
      "type": "payment_info_request"
  }
Create InfoRequest and you will send link to Contact
curl -X POST -H "Content-Type:application/json" "Authorization: Bearer <access_token>" https://api.affinipay.com/contacts/info-requests -d '
  {
      "contact_id": "p_ICBy63BhpJOGzEPpv1Wp0"
      }
  }'
Example response
{
      "id": "ireq_SxPwrMuqAlPIPCFf4M40k",
      "created": {
          "user": "arden@example.com",
          "timestamp": "2021-09-07T22:33:36.767Z",
          "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
          "client_inet_address": "65.36.124.174",
          "client_country_code": "US",
          "client_location": "30.3643,-97.6864",
          "caller_inet_address": "65.36.124.174",
          "caller_country_code": "US",
          "caller_location": "30.3643,-97.6864"
      },
      "modified": {
          "user": "arden@example.com",
          "timestamp": "2021-09-07T22:33:36.767Z",
          "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
          "client_inet_address": "65.36.124.174",
          "client_country_code": "US",
          "client_location": "30.3643,-97.6864",
          "caller_inet_address": "65.36.124.174",
          "caller_country_code": "US",
          "caller_location": "30.3643,-97.6864"
      },
      "owner_id": "org_ayVmT9zfkH46buQT4HtBK",
      "contact_id": "p_ICBy63BhpJOGzEPpv1Wp0",
      "status": "pending",
      "type": "payment_info_request"
  }

  

Create InfoRequest Hash

POST /contacts/info-requests/{inforequest_id}/hash

Creates an InfoRequestHash for the specified InfoRequest.

The InfoRequestHash expires after 30 days. If a user needs to access the URL after that point, you must create a new InfoRequestHash. URI parameters
ParameterDescription
inforequest_idThe system-generated ID of a specific InfoRequest. (ID prefix = ireq_) (required)
Create InfoRequestHash
curl -X POST -H "Content-Type:application/json" "Authorization: Bearer <access_token>" https://api.affinipay.com/contacts/info-requests/ireq_VMV2xYvse0n7mm9TAtNL1/hash
Example response
{
    "hash": "2plbq8454o9jbsqdt7k21qi420m0agga82r5nkih94m4ek4mqkau",
    "url": "https://portal.affinipay.com/?c=2plbq8454o9jbsqdt7k21qi420m0agga82r5nkih94m4ek4mqkau&payment-info",
    "contact_id": "p_Igc4ScIpV9ofmd3VY4QZv"
    }
  

Cancel InfoRequest

PATCH /contacts/info-requests/{info_request_id}

Updates the specified InfoRequest to change its status and cancel it.

URI parameters
ParameterDescription
info_request_idThe system-generated ID of a specific InfoRequest. (ID prefix = <span class="monospace"ireq_</span>) (required)
Cancel InfoRequest
curl -X PATCH -H "Content-Type:application/json" "Authorization: Bearer <access_token>" https://api.affinipay.com/contacts/info-requests/ireq_CGGkI0ovoglyFLadQU5fV -d '
  {
    "status": "canceled"
}'
Example response
{
    "id": "ireq_CGGkI0ovoglyFLadQU5fV",
    "created": {
        "user": "arden@example.com",
        "timestamp": "2021-09-08T13:38:34.383Z",
        "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
        "client_inet_address": "65.36.124.174",
        "client_country_code": "US",
        "client_location": "30.3643,-97.6864",
        "caller_inet_address": "65.36.124.174",
        "caller_country_code": "US",
        "caller_location": "30.3643,-97.6864"
    },
    "modified": {
        "user": "arden@example.com",
        "timestamp": "2021-09-08T13:38:34.383Z",
        "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
        "client_inet_address": "65.36.124.174",
        "client_country_code": "US",
        "client_location": "30.3643,-97.6864",
        "caller_inet_address": "65.36.124.174",
        "caller_country_code": "US",
        "caller_location": "30.3643,-97.6864"
    },
    "owner_id": "org_ayVmT9zfkH46buQT4HtBK",
    "contact_id": "p_ICBy63BhpJOGzEPpv1Wp0",
    "status": "canceled",
    "message": {
        "subject": "Please provide your payment information",
        "body": "Please provide your payment information so we can start our working relationship. This information will be stored securely and we will not make any charges without informing you first."
    },
    "type": "payment_info_request"
}

  

Delete InfoRequest

DELETE /contacts/info-requests/{info_request_id}

Deletes the specified InfoRequest.

URI parameters
ParameterDescription
info_request_idThe system-generated ID of a specific InfoRequest. (ID prefix = ireq_) (required)
Delete an InfoRequest
curl -X DELETE "Content-Type:application/json" "Authorization: Bearer <access_token>" https://api.affinipay.com/contacts/info-requests/ireq_isIcuDGzAvDA2MfKvPFnE
Example response
{
    "id": "ireq_isIcuDGzAvDA2MfKvPFnE",
    "created": {
        "user": "arden@example.com",
        "timestamp": "2021-09-08T16:57:42.130Z",
        "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
        "client_inet_address": "65.36.124.174",
        "client_country_code": "US",
        "client_location": "30.3643,-97.6864",
        "caller_inet_address": "65.36.124.174",
        "caller_country_code": "US",
        "caller_location": "30.3643,-97.6864"
    },
    "modified": {
        "user": "arden@example.com",
        "timestamp": "2021-09-08T16:57:42.130Z",
        "client_id": "41a2c1019e63db49b0efe23b16fea19c685d7c896657470174a1cc91b54cddc7",
        "client_inet_address": "65.36.124.174",
        "client_country_code": "US",
        "client_location": "30.3643,-97.6864",
        "caller_inet_address": "65.36.124.174",
        "caller_country_code": "US",
        "caller_location": "30.3643,-97.6864"
    },
    "owner_id": "org_ayVmT9zfkH46buQT4HtBK",
    "contact_id": "p_ICBy63BhpJOGzEPpv1Wp0",
    "status": "pending",
    "message": {
        "subject": "Please provide your payment information",
        "body": "Please provide your payment information so we can start our working relationship. This information will be stored securely and we will not make any charges without informing you first."
    },
    "type": "payment_info_request"
}

  

Get Bank Accounts

GET /bank-accounts

Retrieves a list of each BankAccount for the current user’s organization.

Retrieve a list of bank accounts
curl -X GET "Authorization: Bearer <access_token>" https://api.affinipay.com/bank-accounts
Example response
[
    {
        "id": "bank_eZX3KANx7JyXDCrMQkdLj",
        "name": "Chase",
        "bank_name": "JPMorgan Chase & Co.",
        "trust": false,
        "account_id": "*****1234",
        "currency": "USD",
        "processing_accounts": [
        {
          "id": "O4dotqecQnuNVM3o9ukr1A",
          "name": "My Operating",
          "required_payment_fields": "cvv,postal_code",
          "accepted_card_types": "VISA,MASTERCARD,AMERICAN_EXPRESS,DISCOVER",
          "cvv_policy": "OPTIONAL",
          "avs_policy": "SUBMIT_IGNORE_RESULT",
          "swipe_cvv_policy": "OPTIONAL",
          "swipe_avs_policy": "SUBMIT_IGNORE_RESULT",
          "swipe_required_payment_fields": "cvv",
          "type": "card"
        }
      ]
    },
    {
        "id": "bank_XugcE9HWGZNdLFLPvmP82",
        "name": "BoA",
        "bank_name": "Bank of America Corporation",
        "trust": true,
        "account_id": "*****9876",
        "currency": "USD",
        "processing_accounts": [
        {
          "id": "QRoxK56MTgmlQrmSbRJnkA",
          "name": "My Trust",
          "required_payment_fields": "cvv,postal_code",
          "accepted_card_types": "VISA,MASTERCARD,AMERICAN_EXPRESS,DISCOVER",
          "cvv_policy": "OPTIONAL",
          "avs_policy": "SUBMIT_IGNORE_RESULT",
          "swipe_cvv_policy": "OPTIONAL",
          "swipe_avs_policy": "SUBMIT_IGNORE_RESULT",
          "swipe_required_payment_fields": "cvv",
          "type": "card"
        }
      ]
    }
]
  

Make Payment

POST /contacts/{contact_id}/make-payment

Creates a Payment for the invoices associated with the specified Contact and listed in the PaymentRequest. The amount is distributed to the oldest invoice first.

URI parameters
ParameterDescription
contact_idThe system-generated ID of a specific contact. (ID prefix = org_ or p_) (required)
Make a payment
curl -X POST -H "Content-Type:application/json" "Authorization: Bearer <access_token>" https://api.affinipay.com/contacts/{contact_id}/make-payment -d '
  {
    "payment_type": "credit_card",
    "token_id": "jHFdPaV_Tiqnoy27ODIBOw",
    "amount": 10,
    "currency": "USD",
    "reference": "payment",
    "receipt_email_addresses": [
    "eripley@example.com"
    ],
    "invoice_ids": [
    "i_LampyIpbNKmoKqB32ZZUG"
    ]
}'
Example response
[
  {
    "id": "pmt_3ttfZ5qulbkBwzIGqFqAN",
    "created": {
      "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
      "timestamp": "2018-02-15T18:32:11.447Z",
      "client_id": "0123456789012345678901234567890123456789012345678901234567890123",
      "client_inet_address": "172.30.2.0",
      "client_country_code": "US",
      "client_location": "30.2966,-97.7663",
      "caller_inet_address": "172.30.2.0",
      "caller_country_code": "US",
      "caller_location": "30.2966,-97.7663"
      },
    "modified": {
      "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
      "timestamp": "2018-02-15T18:32:11.447Z",
      "client_id": "0123456789012345678901234567890123456789012345678901234567890123",
      "client_inet_address": "172.30.2.0",
      "client_country_code": "US",
      "client_location": "30.2966,-97.7663",
      "caller_inet_address": "172.30.2.0",
      "caller_country_code": "US",
      "caller_location": "30.2966,-97.7663"
      },
    "amount": 10,
    "unallocated_amount": 0,
    "transaction_id": "z0Xn-uzXRzWxTPTB2-kDBg",
    "payment_type": "credit_card",
    "contact_id": "p_AGx6xPaOQ9iLyjOHOYT5T",
    "contact": {
      "id": "p_AGx6xPaOQ9iLyjOHOYT5T",
      "deleted": false,
      "test_mode": false,
      "name": "Ellen L Ripley",
      "sort_name": "Ripley Ellen L",
      "preferred_email": "eripley@example.com",
      "owner_id": "org_Y2eJHCXVqjMlXL9EfmBfc",
      "first_name": "Ellen",
      "middle_name": "L",
      "last_name": "Ripley",
      "name_prefix": "Ms",
      "display_name": "Ellen L Ripley",
      "type": "person"
    },
    "owner_id": "org_Y2eJHCXVqjMlXL9EfmBfc",
    "card_type": "VISA",
    "last4_digits": "4242",
    "currency": "USD",
    "bank_account_id": "bank_ngoOybNXKY52w7Jr32kHO",
    "bank_name": "My Bank",
    "bank_account": "*****4321",
    "bank_account_type": "operating",
    "status": "authorized",
    "test_mode": true,
    "reference": "payment",
    "invoices": [
      {
        "id": "i_LampyIpbNKmoKqB32ZZUG",
        "invoice_date": "2018-02-21T00:00:00.000Z",
        "status": "pending",
        "invoice_number": "000016",
        "currency": "USD",
        "type": "invoice"
      }
    ],
    "failure_email_addresses": [
      "eripley@example.com"
    ],
    "direction": "inbound",
    "type": "payment"
    }
  ]
  

Object Types

All request and response content in this API use JSON representations for serialization to and from the server. The following sections detail the properties, data types, and constraints of each of the types present in the API.

  • Boolean. Boolean values are represented using the JSON literal values true and false
  • Date. Date values (with no time component) are represented using the format yyyy-mm-dd
  • Timestamp. All timestamps sent or received by the Gateway use the ISO-8601 format yyyy-MM-dd'T'HH:mm:ss.SSS'Z', including fractional milliseconds, relative to the UTC time zone. For example, the timestamp 2016-08-21T15:32:21.702Z represents an occurrence on August 21, 2016 at 3:32:21.702 PM UTC.

Address

A contact's address. (ID prefix = addr_)

ParameterTypeDescription
typeStringThe resource type, which is used to identify objects when they share the same endpoint. (optional, unmodifiable, always in response)
messagesArray of MessageIssues or general messages that occur during the request are communicated through this object. (optional, ignored in request)
idXIDThe ID of the resource. The length must be 21-26 characters. The value must match the pattern ^([a-z][a-z0-9]{0,3}_)?[0-9A-Za-z]{21}$. (optional, ignored in request, always in response)
createdAuditTraceThe date and time when the resource was created. This field cannot be updated. (optional, ignored in request, always in response)
modifiedAuditTraceThe date and time when the resource was last modified. (optional, ignored in request, always in response)
line1StringThe mailing address of the contact. The length must be 1-64 characters. (required)
line2StringAn additional address field. The length must be no more than 64 characters. (optional)
cityStringThe city where the contact is located. The length must be 1-64 characters. (required)
state_or_provinceStringFor the US and Canada, the 2-letter state or province code where the contact is located. The length must be no more than 64 characters. (optional)
postal_codeStringThe zip code where the contact is located. The length must be 1-10 characters. The value must match the pattern ^[0-9A-Za-z -]+$. (optional)
country_codeStringThe 2-letter ISO 3166 country code where the contact is located.</span>. (required)
preferredBooleanWhether postal mail is the preferred method of contact. The default value is false. (optional)

Contact

An entity (representing a person or business organization) that acts within the AffiniPay Payment Portal system.

Union of:

ContactHash

A generated hash for unprivileged access to a Contact.

ParameterTypeDescription
messagesArray of MessageIssues or general messages that occur during the request are communicated through this object. (optional, ignored in request)
hashStringA unique string that represents temporary, unprivileged access to portal calls.
urlStringThe default portal link from the generated hash.
contact_idXIDThe system-generated ID of a specific Contact. (ID prefix = p_ or org_, optional)

FileUpload

A file reference. (ID prefix = fref_)

ParameterTypeDescription
idXIDThe ID of the resource. The length must be 21-26 characters. The value must match the pattern ^([a-z][a-z0-9]{0,3}_)?[0-9A-Za-z]{21}$. (optional, ignored in request, always in response)
file_nameStringThe name of the file. (optional)
processing_stateStringThe current status of the uploaded file. (always in response)

One of:

  • processing. The attachment/file is being scanned.
  • completed. The attachment/file has been scanned successfully.
  • failed. The attachment/file has been flagged as dangerous and will be purged from the system.
referenceStringA description of the file. (optional)
messagesArray of MessageIssues or general messages that occur during the request are communicated through this object. (optional, ignored in request)
typeStringThe resource type, which is used to identify objects when they share the same endpoint. (optional, unmodifiable, always in response)

InfoRequestHash

A generated hash for unprivileged access to a Contact and outstanding invoices.

ParameterTypeDescription
messagesArray of MessageIssues or general messages that occur during the request are communicated through this object. (optional, ignored in request)
hashStringA unique string that represents temporary, unprivileged access to portal calls.
urlStringThe default portal link from the generated hash.
contact_idXIDThe system-generated ID of a specific Contact. (ID prefix = p_ or org_, optional)

EmailAddress

A contact's email address. (ID prefix = eml_)

ParameterTypeDescription
typeStringThe resource type, which is used to identify objects when they share the same endpoint. (optional, unmodifiable, always in response)
messagesArray of MessageIssues or general messages that occur during the request are communicated through this object. (optional, ignored in request)
idXIDThe ID of the resource. The length must be 21-26 characters. The value must match the pattern ^([a-z][a-z0-9]{0,3}_)?[0-9A-Za-z]{21}$. (optional, ignored in request, always in response)
createdAuditTraceThe date and time when the resource was created. This field cannot be updated. (optional, ignored in request, always in response)
modifiedAuditTraceThe date and time when the resource was last modified. (optional, ignored in request, always in response)
addressStringThe contact's email address. The length must be 1-254 characters. (required)
preferredBooleanWhether an email to this address is the preferred method of contact. The default value is false. (optional)

InfoRequest

A request to save a payment method via the AffiniPay payment portal. (ID prefix = ireq_)

ParameterTypeDescription
idXIDThe ID of the resource. The length must be 21-26 characters. The value must match the pattern ^([a-z][a-z0-9]{0,3}_)?[0-9A-Za-z]{21}$. (optional, ignored in request, always in response)
createdAuditTraceThe date and time when the resource was created. This field cannot be updated. (optional, ignored in request, always in response)
modifiedAuditTraceThe date and time when the resource was last modified. (optional, ignored in request, always in response)
owner_idXIDThe ID of the merchant who owns the resource. The length must be 21-26 characters. The value must match the pattern ^([a-z][a-z0-9]{0,3}_)?[0-9A-Za-z]{21}$.
contact_idXIDThe system-generated ID of a specific Contact. (ID prefix = p_ or org_)
test_modeBooleanWhether this resource is used for testing only. The default value is false. (optional, unmodifiable)
statusStringThe current status of the InfoRequest, within its lifecycle.
  • pending. The InfoRequest has been created and sent to the Contact.
  • viewed. The InfoReqeust has been viewed by the Contact.
  • canceled. The InfoRequest has been canceled by the merchant.

(optional, ignored in request, always in response)

messagemessageThe subject and body of the email to be sent as part of the InfoRequest. If subject and body are blank, the default subject and body set in AffiniPay's Card Vault are used.(required)
typeStringThe resource type, which is used to identify objects when they share the same endpoint.

Organization

An organization. (ID prefix = org_)

ParameterTypeDescription
typeStringThe resource type, which is used to identify objects when they share the same endpoint. The value must be organization. (required, unmodifiable)
messagesArray of MessageIssues or general messages that occur during the request are communicated through this object. (optional, ignored in request)
idXIDThe ID of the resource. The length must be 21-26 characters. The value must match the pattern ^([a-z][a-z0-9]{0,3}_)?[0-9A-Za-z]{21}$. (optional, ignored in request, always in response)
createdAuditTraceThe date and time when the resource was created. This field cannot be updated. (optional, ignored in request, always in response)
modifiedAuditTraceThe date and time when the resource was last modified. (optional, ignored in request, always in response)
sort_nameStringAn auto-generated field that can be used for sorting. The value has the format {last_name} {first_name} {middle_name} {name_suffix} for a person (omitting any value that doesn't exist in the contact), or {name} for an organization. (optional, ignored in request)
display_nameStringAuto-generated field that can be used for display purposes. It will be the same as name if it is populated; otherwise, it will be:
  1. The preferred email address if there is one.
  2. A random email address from the contact's email addresses if there is one.
  3. The contact's ID if there are no email addresses.

(optional, ignored in request, always in response)

preferred_emailStringThe preferred email of the user or a randomly selected one if none is preferred. This is the email address where InfoRequests are sent.(optional, ignored in request)
owner_idXIDThe ID of the merchant who owns the contact. The length must be 21-26 characters. The value must match the pattern ^([a-z][a-z0-9]{0,3}_)?[0-9A-Za-z]{21}$. (optional)
deletedBooleanWhether this contact has been deleted. The default value is false. (optional, ignored in request)
test_modeBooleanWhether this resource is used for testing only. The default value is false. (optional, unmodifiable)
source_idStringAn external system's URI-based identifier for the contact. You can use this ID to uniquely identify and search for a contact. Must conform to one of the following:
  1. RFC 4151
  2. RFC 8141
  3. RFC 4122

The recommended format is partnername:id. For example, if the partner's name is MyPartner, a source ID for a contact might be MyPartner:contact-12345. (optional)

time_zoneStringThe time zone associated with the contact, in Time Zone Database format, such as America/New_York. The length must be no more than 64 characters. (optional)
contact_codeStringAn identifier for the contact that can be used by the merchant. The length must be 1-10 characters. (optional)
invoice_number_patternStringThe pattern used to format the invoice number. It must be in Handlebars format. The following functions are available: ljust rjust center defaultIfEmpty lower upper. The default value is {{rjust senderInvoiceSeq size=6 pad="0"}}. (optional)
ownerSparse version of the OrganizationThe organization that owns the contact. (optional)
organization_idXIDThe ID of the organization to which this contact belongs. (optional)
organizationArray of sparse versions of OrganizationThe organization to which this contact belongs. (optional, ignored in request)
preferred_currencyStringThe ISO 4217 code for the currency used for invoice charges. The length must be no more than 3 characters. (optional)
addressesArray of AddressThe contact's addresses. A contact is limited to 5 addresses. (optional)
phone_numbersArray of PhoneNumberThe contact's phone numbers. A contact is limited to 5 phone numbers. (optional)
email_addressesArray of EmailAddressThe contact's email addresses. A contact is limited to 5 email addresses.(optional)
tagsArray of StringFor a Contact to display in AffiniPay's Card Vault, it must have the tag: default
nameStringThe contact's name. (optional)
membersArray of sparse versions of ContactThe contacts who can act on behalf of this organization. (optional)
notesStringExtra details about the object. (optional, maximum length is 1024 characters)

PaymentMethod

The payment method that specifies payment details. (ID prefix = pmtd_)

ParameterTypeDescription
typeStringThe resource type, which is used to identify objects when they share the same endpoint. (optional, unmodifiable, always in response)
messagesArray of MessageIssues or general messages that occur during the request are communicated through this object. (optional, ignored in request)
idXIDThe ID of the resource. The length must be 21-26 characters. The value must match the pattern ^([a-z][a-z0-9]{0,3}_)?[0-9A-Za-z]{21}$. (optional, ignored in request, always in response)
createdAuditTraceThe date and time when the resource was created. This field cannot be updated. (optional, ignored in request, always in response)
modifiedAuditTraceThe date and time when the resource was last modified. (optional, ignored in request, always in response)
payee_idXIDThe ID of tenant or merchant contact who is being paid. The length must be 21-26 characters. The value must match the pattern ^([a-z][a-z0-9]{0,3}_)?[0-9A-Za-z]{21}$. (ignored in request, always in response)
payment_typePaymentTypeThe type of payment used. (required)

One of:

  • bank_account
  • cash
  • check
  • credit_card
  • other
account_holder_typeStringThe kind of account holder associated with this payment method if the payment_type is bank_account.

One of:

  • individual
  • business
(optional)
nameString
  • For a payment method with a payment_type of bank_account and account_holder_type of business, this is the name of the business.
  • For a payment method with a payment_type of bank_account and account_holder_type of individual, this is the given_name and surname.
  • For a payment method with a payment_type of credit_card, this is the cardholder name.

The length must be no more than 256 characters. (optional)

given_nameStringThe first name of the account holder, for a payment method with a payment_type of bank_account and account_holder_type of individual. The length must be no more than 40 characters. (optional)
surnameStringThe last name of the account holder, for a payment method with a payment_type of bank_account and account_holder_type of individual. The length must be no more than 40 characters. (optional)
nicknameStringA nickname used to make it easier to identify the payment method. The length must be no more than 256 characters. (optional)
account_numberStringThe account number associated with the payment method. The length must be no more than 32 characters. (optional)
bank_nameStringThe name of bank associated with the payment method. The length must be no more than 256 characters. (optional)
bank_account_typeStringFor a bank account payment, whether the account is checking or savings. This is required if the payment_type is bank_account. The length must be no more than 20 characters.

One of:

  • checking
  • savings
(optional)
card_typeStringFor a credit_card payment, the type of credit card.The length must be no more than 64 characters.

One of:

  • MASTERCARD
  • VISA
  • AMERICAN_EXPRESS
  • DISCOVER
  • DINERS_CLUB
  • JCB
  • UNKNOWN
(optional)
expiration_monthIntegerFor a credit card payment, the expiration month for the credit card. This is required if the payment_type is credit_card. (optional)
expiration_yearIntegerFor a credit card payment, the expiration year for the credit card. This is required if the payment_type is credit_card. (optional)
preferredIntegerWhether this is the preferred payment method for the associated contact. The default value is false. (optional)
one_time_tokenStringThe string ID of a one-time payment token, for payment methods that use tokenization. (either one_time_token or saved_payment_token is required)
saved_payment_tokenStringThe string ID of a saved payment token, for payment methods that use tokenization. (either one_time_token or saved_payment_token is required)
test_modeBooleanWhether this payment method is a test payment method. The default value is false. (required)
referenceStringA reference field for partner use to identify the payment method. The length must be no more than 255 characters. (optional)
allow_future_chargesBoolean{Deprecated} Whether the merchant is allowed to run future charges on this payment method. The default value is false. (optional)
authorized_usesEnumerationDefines when this payment method is available to a merchant or their client (optional). Enumeration of:
  • all. This payment method can be used by the merchant (such as in card vault) or by the client (such as in the payment portal).
  • client. This payment method can be used only by the client (such as in the payment portal).
  • merchant. This payment method can be used by the merchant (such as in card vault).
(optional)

Person

A person. (ID prefix = p_)

ParameterTypeDescription
typeStringThe resource type, which is used to identify objects when they share the same endpoint. The value must be person. (required, unmodifiable)
messagesarray of MessageIssues or general messages that occur during the request are communicated through this object. (optional, ignored in request)
idXIDThe ID of the resource. The length must be 21-26 characters. The value must match the pattern ^([a-z][a-z0-9]{0,3}_)?[0-9A-Za-z]{21}$. (optional, ignored in request, always in response)
createdAuditTraceThe date and time when the resource was created. This field cannot be updated. (optional, ignored in request, always in response)
modifiedAuditTraceThe date and time when the resource was last modified. (optional, ignored in request, always in response)
sort_nameStringAn auto-generated field that can be used for sorting. The value has the format {last_name} {first_name} {middle_name} {name_suffix} for a person (omitting any value that doesn't exist in the contact), or {name} for an organization. (optional, ignored in request)
display_nameStringAuto-generated field that can be used for display purposes. It will be the same as name if it is populated; otherwise, it will be:
  1. The preferred email address if there is one.
  2. A random email address from the contact's email addresses if there is one.
  3. The contact's ID if there are no email addresses.

(optional, ignored in request, always in response)

preferred_emailStringThe preferred email of the user or a randomly selected one if none is preferred. This is the email address where InfoRequests are sent.(optional, ignored in request)
owner_idXIDThe ID of the merchant who owns the resource. The length must be 21-26 characters. The value must match the pattern ^([a-z][a-z0-9]{0,3}_)?[0-9A-Za-z]{21}$. (optional)
deletedBooleanWhether this contact has been deleted. The default value is false. (optional, ignored in request)
test_modeBooleanWhether this resource is used for testing only. The default value is false. (optional, unmodifiable)
source_idStringAn external system's URI-based identifier for the contact. You can use this ID to uniquely identify and search for a contact. Must conform to one of the following:
  1. RFC 4151
  2. RFC 8141
  3. RFC 4122

The recommended format is partnername:id. For example, if the partner's name is MyPartner, a source ID for a contact might be MyPartner:contact-12345. (optional)

time_zoneStringThe time zone associated with the contact, in Time Zone Database format, such as America/New_York. The length must be no more than 64 characters. (optional)
contact_codeStringAn identifier for the contact that can be used by the merchant. The length must be 1-10 characters. (optional)
invoice_number_patternStringThe pattern used to format the invoice number. It must be in Handlebars format. The following functions are available: ljust rjust center defaultIfEmpty lower upper. The default value is {{rjust senderInvoiceSeq size=6 pad="0"}}. (optional)
ownerSparse version of the OrganizationThe organization that owns the contact. (optional)
organization_idXIDThe ID of the organization to which this contact belongs. (optional)
organizationArray of sparse versions of OrganizationThe organization to which this contact belongs. (optional, ignored in request)
preferred_currencyStringThe ISO 4217 code for the currency used for invoice charges. The length must be no more than 3 characters. (optional)
addressesArray of AddressThe contact's addresses. A contact is limited to 5 addresses. (optional)
phone_numbersArray of PhoneNumberThe contact's phone numbers. A contact is limited to 5 phone numbers.(optional)
email_addressesArray of EmailAddressThe contact's email addresses. A contact is limited to 5 email addresses.(optional)
tagsArray of StringFor a Contact to display in AffiniPay's Card Vault, it must have the tag: default
first_nameStringThe first name of the person. The length must be no more than 64 characters. (optional)
middle_nameStringThe middle name of the person. The length must be no more than 64 characters. (optional)
last_nameStringThe last name of the person. The length must be no more than 64 characters. (optional)
name_prefixStringThe prefix associated with the person's name. The length must be no more than 20 characters. (optional)
name_suffixStringThe suffix associated with the person's name. The length must be no more than 20 characters. (optional)
nameStringThe person's name. (optional)
notesStringExtra details about the object. (optional, maximum length is 1024 characters)

PhoneNumber

A contact's phone number. (ID prefix = phn)

ParameterTypeDescription
typeStringThe resource type, which is used to identify objects when they share the same endpoint. (optional, unmodifiable, always in response)
messagesarray of MessageIssues or general messages that occur during the request are communicated through this object. (optional, ignored in request)
idXIDThe ID of the resource. The length must be 21-26 characters. The value must match the pattern ^([a-z][a-z0-9]{0,3}_)?[0-9A-Za-z]{21}$. (optional, ignored in request, always in response)
createdAuditTraceThe date and time when the resource was created. This field cannot be updated. (optional, ignored in request, always in response)
modifiedAuditTraceThe date and time when the resource was last modified. (optional, ignored in request, always in response)
numberStringThe contact's phone number. The length must be 5-15 characters. (required)
extensionStringThe contact's phone extension. The length must be no more than 5 characters. (optional)
preferredBooleanWhether a phone call is the preferred method of contact. The default value is false. (optional)

Payment Portal API

Overview

The AffiniPay Payment Platform provides a REST API to enable you to send invoices for payment in our portal.

For a successful integration, you should be familiar with writing code that interacts with REST endpoints using the HTTP protocol as well as the OAuth 2.0 Authorization Framework.

Authentication

The AffiniPay Payment Platform authorizes requests using OAuth 2.0, which identifies and authenticates your partner OAuth application using your OAuth client ID and OAuth client secret. Both are available in the AffiniPay web application.

When you run the OAuth flow, the AffiniPay Payment Platform returns a bearer access token that authenticates your API requests. You must include this access token in API requests in the Authorization header with the Bearer authentication scheme. See the Connect topics to determine which OAuth flow to use.

Testing

Before you put your integration into production use, you should test with a variety of valid and invalid request data to exercise both success and failure scenarios in your application. To make test requests, set the test_mode parameter on each object to true.

If you're creating a test invoice, your request body must include:

  • The bank_account_id for a bank account with its test parameter set to true.
  • A contact_id for a contact with its test_mode parameter set to true.
  • The test_mode parameter set to true for the invoice itself.

Requests and Responses

The Payment Portal REST API only accepts encrypted communications using HTTPS; requests made over unsecured HTTP communications are not accepted. All interactions with the REST API are carried out over a secure connection using TLS 1.2 to safeguard data contents.

All request and response content is represented as JSON.

Requests are standard REST calls made to the Payment Portal API URL:

https://api.affinipay.com

The REST API returns standard HTTP status codes to indicate the success or failure of each operation. Status codes in the 2xx family indicate success, the 4xx family indicates a failure stemming from the data provided in the request, and the 5xx family indicates that the failure is outside the caller's control.

Response CodeDescription
200The operation succeeded
204The operation succeeded, but no response content was returned (normal for APIs that do not return any JSON response).
400The request was malformed.
401Authentication credentials were not provided, or were not valid for the requested operation.
404An item referred to in the request, such as a charge or merchant bank account, was not found.
409There was a state conflict due to an unsupported action, such as an attempt to delete an invoice with a payment or an attempt to create an object that already exists.
422The request could not be processed. This is typically due to validation errors reported in the response.
500An error occurred while processing the request.

Invoices

An invoice lists an amount to be paid.

Search Invoices

GET /invoices

Retrieves a list that includes each Invoice that matches the search criteria provided.

Query parameters
ParameterTypeDescription
qStringThe text filter to apply across all text fields. (optional)
qfStringThe filters to apply against specific fields, in the format field:value. If a field is nested, the dot-separated path must be specified. For example, to search for the time when an invoice was created, use created.timestamp; to search for the status of an invoice, use status. Multiple field:value pairs should be separated by a comma, qf=f1:v1,f2:v2,...fn:vn. Date ranges can be queried using >, >=, <, <= in the format timestamp(>|>=|<|<=)value. The date value to query against must be in the format yyyy-MM-ddTHH:mm:ss.SSSZZ. For example, created.timestamp>2018-06-25T15:45:57.838Z or modified.timestamp<=2017-11-14T12:25:58.891Z. A date range with two bounds should be separated by a comma, qf=f1(>|>=|<|<=)v1,f1(>|>=|<|<=)v2. (optional)
order_byArray of StringThe list of fields to sort by, prefixed with - for descending. To include multiple fields, separate them with a comma. For example, order_by=field1,-field2. (optional)
pageInt32The page number, starting at 1. The default value is 1. (optional)
page_sizeInt32The maximum number of items in the page. (optional)
Search for all invoices
curl -X GET "Authorization: Bearer <access_token>" https://api.affinipay.com/invoices
Example response
{
    "page": 1,
    "page_size": 20,
    "total_entries": 200,
    "results": [
        {
            "id": "i_iXGj6u1uCgonbGQUI3hmu",
            "created": {
                "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
                "timestamp": "2018-06-07T18:10:58.386Z",
                "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
                "client_inet_address": "66.90.249.23",
                "client_country_code": "US",
                "client_location": "30.2414,-97.7687",
                "caller_inet_address": "66.90.249.23",
                "caller_country_code": "US",
                "caller_location": "30.2414,-97.7687"
            },
            "modified": {
                "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
                "timestamp": "2018-06-07T18:12:04.920Z",
                "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
                "client_inet_address": "66.90.249.23",
                "client_country_code": "US",
                "client_location": "30.2414,-97.7687",
                "caller_inet_address": "66.90.249.23",
                "caller_country_code": "US",
                "caller_location": "30.2414,-97.7687"
            },
            "status": "draft",
            "invoice_number": "000024",
            "invoice_date": "2018-06-06T00:00:00.000Z",
            "total_amount": 10000,
            "total_amount_due": 10000,
            "amount_paid": 0,
            "test_mode": false,
            "currency": "USD",
            "bank_account_id": "bank_eZX3KANx7JyXDCrMQkdLj",
            "owner_id": "org_Y2eJHCXVqjMlXL9EfmBfc",
            "contact_id": "p_tup7e7S0e7LIE55qvgXAR",
            "contact": {
                "id": "p_tup7e7S0e7LIE55qvgXAR",
                "test_mode": false,
                "owner_id": "org_Y2eJHCXVqjMlXL9EfmBfc",
                "preferred_email": "eripley@example.com",
                "first_name": "Ellen",
                "last_name": "Ripley",
                "name": "Ellen Ripley",
                "type": "person",
                "sort_name": "Ripley Ellen",
                "display_name": "Ellen Ripley"
            },
            "invoice_payments": [],
            "items": [
                {
                    "id": "li_5cCL6ufx4KcjsM3CJYskH",
                    "description": "Consulting fee",
                    "rate_per_quantity": "10000",
                    "quantity": "1",
                    "rate_type": "units",
                    "total": 10000
                }
            ],
            "line_items": [
                {
                    "id": "li_5cCL6ufx4KcjsM3CJYskH",
                    "description": "Consulting fee",
                    "rate_per_quantity": "10000",
                    "quantity": "1",
                    "rate_type": "units",
                    "total": 10000
                }
            ],
            "invoice_messages": [],
            "attachments": [],
            "type": "invoice"
        },
        .
        .
        .
        {
            "id": "i_uYUXQfch0FBT46oyDnLKB",
            "created": {
                "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
                "timestamp": "2018-06-07T18:24:57.172Z",
                "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
                "client_inet_address": "66.90.249.23",
                "client_country_code": "US",
                "client_location": "30.2966,-97.7663",
                "caller_inet_address": "66.90.249.23",
                "caller_country_code": "US",
                "caller_location": "30.2966,-97.7663"
            },
            "modified": {
                "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
                "timestamp": "2018-06-07T18:24:57.293Z",
                "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
                "client_inet_address": "66.90.249.23",
                "client_country_code": "US",
                "client_location": "30.2966,-97.7663",
                "caller_inet_address": "66.90.249.23",
                "caller_country_code": "US",
                "caller_location": "30.2966,-97.7663"
            },
            "status": "draft",
            "invoice_number": "000025",
            "invoice_date": "2018-06-06T00:00:00.000Z",
            "total_amount": 12500,
            "total_amount_due": 12500,
            "amount_paid": 0,
            "test_mode": false,
            "currency": "USD",
            "bank_account_id": "bank_eZX3KANx7JyXDCrMQkdLj",
            "owner_id": "org_Y2eJHCXVqjMlXL9EfmBfc",
            "contact_id": "p_ZN7lC1sqzdCvJ3AiykD5D",
            "contact": {
                "id": "p_ZN7lC1sqzdCvJ3AiykD5D",
                "test_mode": false,
                "owner_id": "org_Y2eJHCXVqjMlXL9EfmBfc",
                "preferred_email": "sconner@example.com",
                "first_name": "Sarah",
                "last_name": "Conner",
                "name": "Sarah Conner",
                "type": "person",
                "sort_name": "Conner Sarah",
                "display_name": "Sarah Conner"
            },
            "invoice_payments": [],
            "items": [
                {
                    "id": "li_ETGlhTjm4yB2bDlz1sbzv",
                    "description": "Consulting fee",
                    "rate_per_quantity": "12500",
                    "quantity": "1",
                    "rate_type": "units",
                    "total": 12500
                }
            ],
            "line_items": [
                {
                    "id": "li_ETGlhTjm4yB2bDlz1sbzv",
                    "description": "Consulting fee",
                    "rate_per_quantity": "12500",
                    "quantity": "1",
                    "rate_type": "units",
                    "total": 12500
                }
            ],
            "invoice_messages": [],
            "attachments": [],
            "type": "invoice"
        }
    ]
}

  

Create Invoice

POST /invoices

Before you begin, see the related developer documentation, which contains a list of all the steps required before you create an invoice.

Creates an Invoice using the properties included in the request. If you are creating an invoice for test purposes, set test_mode to true.

You can upload files to the system. After the files complete antivirus processing, you can attach them to an Invoice when you create or PATCH the Invoice. An attachment is purged from the system automatically after one year.

Create invoice
curl -X POST -H "Content-Type:application/json" "Authorization: Bearer <access_token>" https://api.affinipay.com/invoices -d '
  {
    "contact_id": "p_tup7e7S0e7LIE55qvgXAR",
    "bank_account_id": "bank_ngoOybNXKY52w7Jr32kHO",
    "invoice_date": "2018-06-06",
    "currency": "USD",
    "line_items": [
      {
        "description": "Consulting fee",
        "rate_per_quantity": "10000",
        "quantity": "1",
        "rate_type": "units"
      }],
    "invoice_messages": [
      {
        "email_addresses": ["eripley@example.com", "billing@example.com"]
      }],
    "attachments": [
      {
        "id": "fref_vmaFw5ARaXFOFgEH7gtCa"
      }],
    "test_mode": "true"
  }'
Example response
{
      "id": "i_WMxCGPfFSeHKgdoLsPMus",
      "created": {
          "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
          "timestamp": "2018-09-27T20:21:15.440Z",
          "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
          "client_inet_address": "66.90.249.23",
          "client_country_code": "US",
          "client_location": "30.2955,-97.8133",
          "caller_inet_address": "66.90.249.23",
          "caller_country_code": "US",
          "caller_location": "30.2955,-97.8133"
      },
      "modified": {
          "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
          "timestamp": "2018-09-27T20:21:15.440Z",
          "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
          "client_inet_address": "66.90.249.23",
          "client_country_code": "US",
          "client_location": "30.2955,-97.8133",
          "caller_inet_address": "66.90.249.23",
          "caller_country_code": "US",
          "caller_location": "30.2955,-97.8133"
      },
      "status": "pending",
      "invoice_number": "000028",
      "invoice_date": "2018-09-27T00:00:00.000Z",
      "total_amount": 10000,
      "total_amount_due": 10000,
      "amount_paid": 0,
      "test_mode": true,
      "currency": "USD",
      "bank_account_id": "bank_ngoOybNXKY52w7Jr32kHO",
      "owner_id": "org_Y2eJHCXVqjMlXL9EfmBfc",
      "contact_id": "p_tup7e7S0e7LIE55qvgXAR",
      "contact": {
          "id": "p_tup7e7S0e7LIE55qvgXAR",
          "test_mode": false,
          "owner_id": "org_Y2eJHCXVqjMlXL9EfmBfc",
          "preferred_email": "eripley@example.com",
          "first_name": "Ellen",
          "last_name": "Ripley",
          "name": "Ellen Ripley",
          "type": "person",
          "sort_name": "Ripley Ellen",
          "display_name": "Ellen Ripley"
      },
      "invoice_payments": [],
      "items": [
          {
              "id": "li_mXwlgmkwdBpr5e6wtTtA8",
              "description": "Consulting fee",
              "rate_per_quantity": "10000",
              "quantity": "1",
              "rate_type": "units",
              "total": 10000
          }
      ],
      "line_items": [
          {
              "id": "li_mXwlgmkwdBpr5e6wtTtA8",
              "description": "Consulting fee",
              "rate_per_quantity": "10000",
              "quantity": "1",
              "rate_type": "units",
              "total": 10000
          }
      ],
      "invoice_messages": [
          {
              "id": "imsg_Rub9yEhVt5oo37On70y0H",
              "created": {
                  "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
                  "timestamp": "2018-09-27T20:21:15.440Z",
                  "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
                  "client_inet_address": "66.90.249.23",
                  "client_country_code": "US",
                  "client_location": "30.2955,-97.8133",
                  "caller_inet_address": "66.90.249.23",
                  "caller_country_code": "US",
                  "caller_location": "30.2955,-97.8133"
              },
              "modified": {
                  "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
                  "timestamp": "2018-09-27T20:21:15.440Z",
                  "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
                  "client_inet_address": "66.90.249.23",
                  "client_country_code": "US",
                  "client_location": "30.2955,-97.8133",
                  "caller_inet_address": "66.90.249.23",
                  "caller_country_code": "US",
                  "caller_location": "30.2955,-97.8133"
              },
              "email_addresses": [
                  "eripley@example.com",
                  "billing@example.com"
              ],
              "subject": "Request for Payment",
              "body": "\n    <!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n\n<link href=\"https://fonts.googleapis.com/css?family=Lato|Source+Sans+Pro\" rel=\"stylesheet\"> \n<meta http-equiv=\"Content-Type\" content=\"text/html charset=UTF-8\" />\n\n<body bgcolor=\"#143F6C\" color=\"#333333\" style=\"background: #143F6C; font-family: 'Source Sans Pro', sans-serif; color: #333; padding-top: 15px;\">\n    <table align=\"center\" bgcolor=\"#FFFFFF\" style=\"width: 75%; background-color: #FFF; margin: auto; padding: 24px;\">\n        \n            \n                \n                    

\n <font family=\"Helvetica, Arial,sans-serif\">Heather Law LLC said:</font>\n

\n

\n <font family=\"Helvetica, Arial,sans-serif\">For your convenience, our firm accepts payments online. To make a payment, please click the link below. Contact our office directly if you have any questions.</font>\n

\n \n\n

\n \n

\n \n \n \n <p align=\"center\" style=\"text-align: center; margin-top: 24px; margin-bottom: 24px;\">\n \n \n \n <a style=\"padding: 8px 15px; color: #FFF; background: #046FDC; text-decoration: none;\" class=\"btnPayNow\" href=\"https://qa.portal.affinipay.com/?c=pn0q3moptqusjs2ajer8gis2itu3un77q3keh4q8efde2d8rskh3\">\n <font family=\"Helvetica, Arial,sans-serif\">Pay Now</font>\n </a>\n \n </p>\n \n <table bgcolor=\"#FFFFFF\" width=\"100%\" border=\"0\" cellpadding=\"6\">\n \n <td style=\"font-size: 20px; border-bottom: 1px solid #EEE; color: #666\">\n <font family=\"Helvetica, Arial,sans-serif\" color=\"#666666\">Balance Due</font>\n </td>\n <td style=\"font-size: 20px; text-align:right; color: #000; font-family: 'Lato', sans-serif; border-bottom: 1px solid #EEE;\">\n <font family=\"Helvetica, Arial,sans-serif\" color=\"#000000\">$200.00</font>\n </td>\n \n </table>\n \n\n <p style=\"margin-top: 24px; border-top: 1px solid #EEE; padding-top: 8px;\">\n <img border=\"0\" width=\"200\" height=\"50\" src=\"cid:poweredBy\" alt=\"Powered By AffiniPay\">\n </p>\n \n \n \n\n </table>\n\n <p style=\"padding: 36px 0px; text-align: center; font-size: 14px; color: #FFF;\">\n <font color=\"#FFFFFF\">\n Heather Law LLC
\n \n 98723 Main Street, Austin, TX 78730\n \n </font>\n </p>\n\n</body>\n</html>\n", "status": "sent", "type": "invoice_message" } ], "scheduled_payment_requests": [], "reference": "1357", "presentment_status": "sent", "attachments": [ { "id": "fref_vmaFw5ARaXFOFgEH7gtCa", "created": { "user": "org_Y2eJHCXVqjMlXL9EfmBfc", "timestamp": "2018-09-27T20:21:15.440Z", "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910", "client_inet_address": "66.90.249.23", "client_country_code": "US", "client_location": "30.2961,-97.7369", "caller_inet_address": "66.90.249.23", "caller_country_code": "US", "caller_location": "30.2961,-97.7369" }, "modified": { "user": "SERVER", "timestamp": "2018-09-27T20:21:15.949Z", "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910", "client_inet_address": "0.0.0.0", "client_country_code": "US", "client_location": "30.2961,-97.7369", "caller_inet_address": "0.0.0.0", "caller_country_code": "US", "caller_location": "30.2961,-97.7369" }, "file_name": "invoice123456789.pdf", "processing_state": "completed", "type": "invoice_file_reference" } ], "type": "invoice" }

Get Invoice

GET /invoices/{invoice_id}

Retrieves the specified Invoice.

URI parameters
ParameterDescription
invoice_idThe system-generated ID of a specific invoice. (ID prefix = i_) (required)
Search for invoice
curl -X GET "Authorization: Bearer <access_token>" https://api.affinipay.com/invoices/i_LiGDAYi60vgvmRhciiUJh
Example response
{
    "id": "i_LiGDAYi60vgvmRhciiUJh",
    "created": {
        "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
        "timestamp": "2018-06-11T14:20:35.977Z",
        "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
        "client_inet_address": "66.90.249.23",
        "client_country_code": "US",
        "client_location": "30.2966,-97.7663",
        "caller_inet_address": "66.90.249.23",
        "caller_country_code": "US",
        "caller_location": "30.2966,-97.7663"
    },
    "modified": {
        "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
        "timestamp": "2018-06-11T14:20:36.048Z",
        "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
        "client_inet_address": "66.90.249.23",
        "client_country_code": "US",
        "client_location": "30.2966,-97.7663",
        "caller_inet_address": "66.90.249.23",
        "caller_country_code": "US",
        "caller_location": "30.2966,-97.7663"
    },
    "status": "draft",
    "invoice_number": "000027",
    "invoice_date": "2018-06-10T00:00:00.000Z",
    "total_amount": 10000,
    "total_amount_due": 10000,
    "amount_paid": 0,
    "test_mode": true,
    "currency": "USD",
    "bank_account_id": "bank_ngoOybNXKY52w7Jr32kHO",
    "owner_id": "org_Y2eJHCXVqjMlXL9EfmBfc",
    "contact_id": "p_tup7e7S0e7LIE55qvgXAR",
    "contact": {
        "id": "p_tup7e7S0e7LIE55qvgXAR",
        "test_mode": false,
        "owner_id": "org_Y2eJHCXVqjMlXL9EfmBfc",
        "preferred_email": "eripley@example.com",
        "first_name": "Ellen",
        "last_name": "Ripley",
        "sort_name": "Ripley Ellen",
        "name": "Ellen Ripley",
        "type": "person",
        "display_name": "Ellen Ripley"
    },
    "invoice_payments": [],
    "items": [
        {
            "id": "li_WqzRb8t8CU93rblNOFr31",
            "description": "Consulting fee",
            "rate_per_quantity": "10000",
            "quantity": "1",
            "rate_type": "units",
            "total": 10000
        }
    ],
    "line_items": [
        {
            "id": "li_WqzRb8t8CU93rblNOFr31",
            "description": "Consulting fee",
            "rate_per_quantity": "10000",
            "quantity": "1",
            "rate_type": "units",
            "total": 10000
        }
    ],
    "invoice_messages": [],
    "attachments": [],
    "type": "invoice"
  }

  

Update Invoice

PATCH /invoices/{invoice_id}

Updates the specified Invoice's current property values with values that you provide. Any properties that you do not specify in the PATCH will be left as-is.

To add attachments to an invoice, you must specify an array with that includes the final list of attachments. To delete attachments from the invoice, include an empty attachments array in the PATCH.

URI parameters
ParameterDescription
invoice_idThe system-generated ID of a specific invoice. (ID prefix = i_) (required)
Add attachment to an invoice
curl -X PATCH -H "Content-Type:application/json" "Authorization: Bearer <access_token>" https://api.affinipay.com/invoices/i_T4rJd7os3rmglznNCnrNN -d '
  {
    "attachments": [
      {
        "id": "fref_uJ2CAdyGNdPZzuSJDFsqe"
      }]
  }'
Example response
{
    "id": "i_iXGj6u1uCgonbGQUI3hmu",
    "created": {
        "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
        "timestamp": "2018-09-28T00:00:00.000Z",
        "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
        "client_inet_address": "66.90.249.23",
        "client_country_code": "US",
        "client_location": "30.2414,-97.7687",
        "caller_inet_address": "66.90.249.23",
        "caller_country_code": "US",
        "caller_location": "30.2414,-97.7687"
    },
    "modified": {
        "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
        "timestamp": "2018-09-28T00:00:00.000Z",
        "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
        "client_inet_address": "66.90.249.23",
        "client_country_code": "US",
        "client_location": "30.2414,-97.7687",
        "caller_inet_address": "66.90.249.23",
        "caller_country_code": "US",
        "caller_location": "30.2414,-97.7687"
    },
    "status": "draft",
    "invoice_number": "000024",
    "invoice_date": "2018-09-28T00:00:00.000Z",
    "total_amount": 10000,
    "total_amount_due": 10000,
    "amount_paid": 0,
    "test_mode": false,
    "currency": "USD",
    "bank_account_id": "bank_PQ93nb6qb9gwn477gcJKL",
    "owner_id": "org_Y2eJHCXVqjMlXL9EfmBfc",
    "contact_id": "p_tup7e7S0e7LIE55qvgXAR",
    "contact": {
        "id": "p_tup7e7S0e7LIE55qvgXAR",
        "test_mode": false,
        "owner_id": "org_Y2eJHCXVqjMlXL9EfmBfc",
        "preferred_email": "eripley@example.com",
        "first_name": "Ellen",
        "last_name": "Ripley",
        "sort_name": "Ripley Ellen",
        "name": "Ellen Ripley",
        "type": "person",
        "display_name": "Ellen Ripley"
    },
    "invoice_payments": [],
    "items": [
        {
            "id": "li_5cCL6ufx4KcjsM3CJYskH",
            "description": "Consulting fee",
            "rate_per_quantity": "10000",
            "quantity": "1",
            "rate_type": "units",
            "total": 10000
        }
    ],
    "line_items": [
        {
            "id": "li_5cCL6ufx4KcjsM3CJYskH",
            "description": "Consulting fee",
            "rate_per_quantity": "10000",
            "quantity": "1",
            "rate_type": "units",
            "total": 10000
        }
    ],
    "invoice_messages": [],
    "attachments": [
      {
        "id": "fref_uJ2CAdyGNdPZzuSJDFsqe",
        "created": {
            "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
            "timestamp": "2018-09-28T00:00:00.000Z",
            "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
            "client_inet_address": "66.90.249.23",
            "client_country_code": "US",
            "client_location": "30.2961,-97.7369",
            "caller_inet_address": "66.90.249.23",
            "caller_country_code": "US",
            "caller_location": "30.2961,-97.7369"
        },
        "modified": {
            "user": "SERVER",
            "timestamp": "2018-09-28T00:00:00.000Z",
            "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
            "client_inet_address": "0.0.0.0",
            "client_country_code": "US",
            "client_location": "30.2961,-97.7369",
            "caller_inet_address": "0.0.0.0",
            "caller_country_code": "US",
            "caller_location": "30.2961,-97.7369"
        },
        "file_name": "invoice123456787.pdf",
        "processing_state": "completed",
        "type": "invoice_file_reference"
        }
      ],
    "type": "invoice"
}
  

Delete Invoice

DELETE /invoices/{invoice_id}

Deletes the specified Invoice.

URI parameters
ParameterDescription
invoice_idThe system-generated ID of a specific invoice. (ID prefix = i_) (required)
Delete invoice
curl -X DELETE "Authorization: Bearer <access_token>" https://api.affinipay.com/invoices/i_uYUXQfch0FBT46oyDnLKB
Example response
{
    "id": "i_uYUXQfch0FBT46oyDnLKB",
    "created": {
        "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
        "timestamp": "2018-06-07T18:24:57.172Z",
        "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
        "client_inet_address": "66.90.249.23",
        "client_country_code": "US",
        "client_location": "30.2966,-97.7663",
        "caller_inet_address": "66.90.249.23",
        "caller_country_code": "US",
        "caller_location": "30.2966,-97.7663"
    },
    "modified": {
        "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
        "timestamp": "2018-06-07T18:24:57.293Z",
        "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
        "client_inet_address": "66.90.249.23",
        "client_country_code": "US",
        "client_location": "30.2966,-97.7663",
        "caller_inet_address": "66.90.249.23",
        "caller_country_code": "US",
        "caller_location": "30.2966,-97.7663"
    },
    "status": "draft",
    "invoice_number": "000025",
    "invoice_date": "2018-06-06T00:00:00.000Z",
    "total_amount": 12500,
    "total_amount_due": 12500,
    "amount_paid": 0,
    "deleted": true,
    "test_mode": false,
    "currency": "USD",
    "bank_account_id": "bank_eZX3KANx7JyXDCrMQkdLj",
    "owner_id": "org_Y2eJHCXVqjMlXL9EfmBfc",
    "contact_id": "p_ZN7lC1sqzdCvJ3AiykD5D",
    "contact": {
        "id": "p_ZN7lC1sqzdCvJ3AiykD5D",
        "test_mode": false,
        "owner_id": "org_Y2eJHCXVqjMlXL9EfmBfc",
        "preferred_email": "sconner@example.com",
        "first_name": "Sarah",
        "last_name": "Conner",
        "name": "Sarah Conner",
        "type": "person",
        "sort_name": "Conner Sarah",
        "display_name": "Sarah Conner"
    },
    "invoice_payments": [],
    "items": [
        {
            "id": "li_ETGlhTjm4yB2bDlz1sbzv",
            "description": "Consulting fee",
            "rate_per_quantity": "12500",
            "quantity": "1",
            "rate_type": "units",
            "total": 12500
        }
    ],
    "line_items": [
        {
            "id": "li_ETGlhTjm4yB2bDlz1sbzv",
            "description": "Consulting fee",
            "rate_per_quantity": "12500",
            "quantity": "1",
            "rate_type": "units",
            "total": 12500
        }
    ],
    "invoice_messages": [],
    "attachments": [],
    "type": "invoice"
}

  

Create Invoice Message

POST /invoices/{invoice_id}/messages

Creates an InvoiceMessage, which sends an email regarding the specified invoice. Use this to re-send a link to the payment portal, where users pay their invoices.

URI Parameters
ParameterDescription
invoice_idThe system-generated ID of a specific invoice. (ID prefix = i_) (required)
Create invoice message
curl -X POST -H "Content-Type:application/json" "Authorization: Bearer <access_token>" https://api.affinipay.com/invoices/i_bw0PHxBEVQ5A266w9cYvo/messages -d '
  {
    "email_addresses": ["eripley@example.com", "billing@example.com"]
  }'
Example response
{
    "id": "imsg_eSWSauSed6r0BIbFROu7R",
    "created": {
        "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
        "timestamp": "2018-06-07T18:33:47.742Z",
        "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
        "client_inet_address": "66.90.249.23",
        "client_country_code": "US",
        "client_location": "30.2966,-97.7663",
        "caller_inet_address": "66.90.249.23",
        "caller_country_code": "US",
        "caller_location": "30.2966,-97.7663"
    },
    "modified": {
        "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
        "timestamp": "2018-06-07T18:33:47.742Z",
        "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
        "client_inet_address": "66.90.249.23",
        "client_country_code": "US",
        "client_location": "30.2966,-97.7663",
        "caller_inet_address": "66.90.249.23",
        "caller_country_code": "US",
        "caller_location": "30.2966,-97.7663"
    },
    "email_addresses": [
        "eripley@example.com",
        "billing@example.com"
    ],
    "subject": "Your AffiniPay Invoice [000024]",
    "body": "\n    <!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n\n<link href=\"https://fonts.googleapis.com/css?family=Lato|Source+Sans+Pro\" rel=\"stylesheet\"> \n<meta http-equiv=\"Content-Type\" content=\"text/html charset=UTF-8\" />\n\n<body bgcolor=\"#143F6C\" color=\"#333333\" style=\"background: #143F6C; font-family: 'Source Sans Pro', sans-serif; color: #333; padding-top: 15px;\">\n    <table align=\"center\" bgcolor=\"#FFFFFF\" style=\"width: 75%; background-color: #FFF; margin: auto; padding: 24px;\">\n        \n            \n                \n                    

\n <font family=\"Helvetica, Arial,sans-serif\">\n My Company has sent you a payment request.\n </font>\n

\n \n\n

\n \n

\n \n \n \n <p align=\"center\" style=\"text-align: center; margin-top: 24px; margin-bottom: 24px;\">\n \n \n \n <a style=\"padding: 8px 15px; color: #FFF; background: #046FDC; text-decoration: none;\" class=\"btnPayNow\" href=\"https://qa.portal.affinipay.com/?c=3glspjroe0sm3las1e0g5hjete4ccgmiodi86dsd62ltkf9rs0n\">\n <font family=\"Helvetica, Arial,sans-serif\">Pay Now</font>\n </a>\n \n </p>\n \n <table bgcolor=\"#FFFFFF\" width=\"100%\" border=\"0\" cellpadding=\"6\">\n \n <td style=\"font-size: 20px; border-bottom: 1px solid #EEE; color: #666\">\n <font family=\"Helvetica, Arial,sans-serif\" color=\"#666666\">Balance Due</font>\n </td>\n <td style=\"font-size: 20px; text-align:right; color: #000; font-family: 'Lato', sans-serif; border-bottom: 1px solid #EEE;\">\n <font family=\"Helvetica, Arial,sans-serif\" color=\"#000000\">$100.00</font>\n </td>\n \n </table>\n \n\n <p style=\"margin-top: 24px; border-top: 1px solid #EEE; padding-top: 8px;\">\n <img border=\"0\" width=\"200\" height=\"50\" src=\"cid:poweredBy\" alt=\"Powered By AffiniPay\">\n </p>\n \n \n \n\n </table>\n\n <p style=\"padding: 36px 0px; text-align: center; font-size: 14px; color: #FFF;\">\n <font color=\"#FFFFFF\">\n My Company
\n \n 98723 Main Street, Austin, TX 78730\n \n </font>\n </p>\n\n</body>\n</html>\n", "status": "sent", "type": "invoice_message"}

Download Attachment

GET /invoices/{invoice_id}/attachments/{attachment-id}

Retrieves the specified file attached to the specified invoice. Set the Accept header to application/octet-stream to download the file in its binary form.

URI parameters
ParameterDescription
invoice_idThe system-generated ID of an invoice (ID prefix = i_) (required)
attachment_idThe system-generated ID of an attachment (ID prefix = fref_) (required)
Download an invoice attachment
curl -X GET "Authorization: Bearer <access_token>" -H 'Accept: application/octet-stream' https://api.affinipay.com/invoices/XXX/attachments/XXX

Delete Attachment

DELETE /invoices/{invoice_id}/attachments/{attachment_id}

Removes the specified file from the its associated invoice and deletes it from the system.

URI parameters
ParameterDescription
invoice_idThe system-generated ID of an invoice (ID prefix = inv_) (required)
attachment_idThe system-generated ID of an invoice attachment (ID prefix = fref_) (required)
Delete an attachment
curl -X DELETE "Authorization: Bearer <access_token>" https://api.affinipay.com/invoices/i_WMxCGPfFSeHKgdoLsPMus/attachments/fref_vmaFw5ARaXFOFgEH7gtCa
Example response
{
      "id": "i_WMxCGPfFSeHKgdoLsPMus",
      "created": {
          "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
          "timestamp": "2018-09-27T20:21:15.440Z",
          "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
          "client_inet_address": "66.90.249.23",
          "client_country_code": "US",
          "client_location": "30.2955,-97.8133",
          "caller_inet_address": "66.90.249.23",
          "caller_country_code": "US",
          "caller_location": "30.2955,-97.8133"
      },
      "modified": {
          "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
          "timestamp": "2018-09-27T20:21:15.440Z",
          "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
          "client_inet_address": "66.90.249.23",
          "client_country_code": "US",
          "client_location": "30.2955,-97.8133",
          "caller_inet_address": "66.90.249.23",
          "caller_country_code": "US",
          "caller_location": "30.2955,-97.8133"
      },
      "status": "pending",
      "invoice_number": "000028",
      "invoice_date": "2018-09-27T00:00:00.000Z",
      "total_amount": 10000,
      "total_amount_due": 10000,
      "amount_paid": 0,
      "test_mode": true,
      "currency": "USD",
      "bank_account_id": "bank_ngoOybNXKY52w7Jr32kHO",
      "owner_id": "org_Y2eJHCXVqjMlXL9EfmBfc",
      "contact_id": "p_tup7e7S0e7LIE55qvgXAR",
      "contact": {
          "id": "p_tup7e7S0e7LIE55qvgXAR",
          "test_mode": false,
          "owner_id": "org_Y2eJHCXVqjMlXL9EfmBfc",
          "preferred_email": "eripley@example.com",
          "first_name": "Ellen",
          "last_name": "Ripley",
          "name": "Ellen Ripley",
          "type": "person",
          "sort_name": "Ripley Ellen",
          "display_name": "Ellen Ripley"
      },
      "invoice_payments": [],
      "items": [
          {
              "id": "li_mXwlgmkwdBpr5e6wtTtA8",
              "description": "Consulting fee",
              "rate_per_quantity": "10000",
              "quantity": "1",
              "rate_type": "units",
              "total": 10000
          }
      ],
      "line_items": [
          {
              "id": "li_mXwlgmkwdBpr5e6wtTtA8",
              "description": "Consulting fee",
              "rate_per_quantity": "10000",
              "quantity": "1",
              "rate_type": "units",
              "total": 10000
          }
      ],
      "invoice_messages": [
          {
              "id": "imsg_Rub9yEhVt5oo37On70y0H",
              "created": {
                  "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
                  "timestamp": "2018-09-27T20:21:15.440Z",
                  "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
                  "client_inet_address": "66.90.249.23",
                  "client_country_code": "US",
                  "client_location": "30.2955,-97.8133",
                  "caller_inet_address": "66.90.249.23",
                  "caller_country_code": "US",
                  "caller_location": "30.2955,-97.8133"
              },
              "modified": {
                  "user": "org_Y2eJHCXVqjMlXL9EfmBfc",
                  "timestamp": "2018-09-27T20:21:15.440Z",
                  "client_id": "c2eef76c8abc09f3c0a5da91edc45a3e8cb7dbf2f18cb4cbb11cd32d72802910",
                  "client_inet_address": "66.90.249.23",
                  "client_country_code": "US",
                  "client_location": "30.2955,-97.8133",
                  "caller_inet_address": "66.90.249.23",
                  "caller_country_code": "US",
                  "caller_location": "30.2955,-97.8133"
              },
              "email_addresses": [
                  "eripley@example.com",
                  "billing@example.com"
              ],
              "subject": "Request for Payment",
              "body": "\n    <!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n\n<link href=\"https://fonts.googleapis.com/css?family=Lato|Source+Sans+Pro\" rel=\"stylesheet\"> \n<meta http-equiv=\"Content-Type\" content=\"text/html charset=UTF-8\" />\n\n<body bgcolor=\"#143F6C\" color=\"#333333\" style=\"background: #143F6C; font-family: 'Source Sans Pro', sans-serif; color: #333; padding-top: 15px;\">\n    <table align=\"center\" bgcolor=\"#FFFFFF\" style=\"width: 75%; background-color: #FFF; margin: auto; padding: 24px;\">\n        \n            \n                \n                    

\n <font family=\"Helvetica, Arial,sans-serif\">Heather Law LLC said:</font>\n

\n

\n <font family=\"Helvetica, Arial,sans-serif\">For your convenience, our firm accepts payments online. To make a payment, please click the link below. Contact our office directly if you have any questions.</font>\n

\n \n\n

\n \n

\n \n \n \n <p align=\"center\" style=\"text-align: center; margin-top: 24px; margin-bottom: 24px;\">\n \n \n \n <a style=\"padding: 8px 15px; color: #FFF; background: #046FDC; text-decoration: none;\" class=\"btnPayNow\" href=\"https://qa.portal.affinipay.com/?c=pn0q3moptqusjs2ajer8gis2itu3un77q3keh4q8efde2d8rskh3\">\n <font family=\"Helvetica, Arial,sans-serif\">Pay Now</font>\n </a>\n \n </p>\n \n <table bgcolor=\"#FFFFFF\" width=\"100%\" border=\"0\" cellpadding=\"6\">\n \n <td style=\"font-size: 20px; border-bottom: 1px solid #EEE; color: #666\">\n <font family=\"Helvetica, Arial,sans-serif\" color=\"#666666\">Balance Due</font>\n </td>\n <td style=\"font-size: 20px; text-align:right; color: #000; font-family: 'Lato', sans-serif; border-bottom: 1px solid #EEE;\">\n <font family=\"Helvetica, Arial,sans-serif\" color=\"#000000\">$200.00</font>\n </td>\n \n </table>\n \n\n <p style=\"margin-top: 24px; border-top: 1px solid #EEE; padding-top: 8px;\">\n <img border=\"0\" width=\"200\" height=\"50\" src=\"cid:poweredBy\" alt=\"Powered By AffiniPay\">\n </p>\n \n \n \n\n </table>\n\n <p style=\"padding: 36px 0px; text-align: center; font-size: 14px; color: #FFF;\">\n <font color=\"#FFFFFF\">\n Heather Law LLC
\n \n 98723 Main Street, Austin, TX 78730\n \n </font>\n </p>\n\n</body>\n</html>\n", "status": "sent", "type": "invoice_message" } ], "scheduled_payment_requests": [], "reference": "1357", "presentment_status": "sent", "attachments": [], "type": "invoice" }

Search Payments

GET /payments

Retrieves a list of each Payment that matches the search criteria provided.

Query parameters
ParameterTypeDescription
start_datedatetimeLimits search results to payments made after the given date. Note: This does not work with q and qf filters. (optional)
end_datedatetimeLimits search results to payments made before the given date. Note: This does not work with q and qf filters. (optional)
qStringThe text filter to apply across all text fields. (optional)
qfStringThe filters to apply against specific fields, in the format field:value. If a field is nested, the dot-separated path must be specified. For example, to search for the time when an invoice was created, use created.timestamp; to search for the status of an invoice, use status. Multiple field:value pairs should be separated by a comma, qf=f1:v1,f2:v2,...fn:vn. Date ranges can be queried using >, >=, <, <= in the format timestamp(>|>=|<|<=)value. The date value to query against must be in the format yyyy-MM-ddTHH:mm:ss.SSSZZ. For example, created.timestamp>2018-06-25T15:45:57.838Z or modified.timestamp<=2017-11-14T12:25:58.891Z. A date range with two bounds should be separated by a comma, qf=f1(>|>=|<|<=)v1,f1(>|>=|<|<=)v2. (optional)
order_byArray of StringThe list of fields to sort by, prefixed with - for descending. To include multiple fields, separate them with a comma. For example, order_by=field1,-field2. (optional)
pageInt32The page number, starting at 1. The default value is 1. (optional)
page_sizeInt32The maximum number of items in the page. (optional)
Search for payments after June 1, 2018
curl -X GET "Authorization: Bearer <access_token>" https://api.affinipay.com/payments/?start_date=2018-06-01T00:00:00.000Z
Example response
{
    "page": 1,
    "page_size": 20,
    "total_entries": 1,
    "results": [
        {
            "id": "pmt_QwktHTsAFnDoLRQYHJQjF",
            "created": {
                "user": "ANONYMOUS",
                "timestamp": "2018-06-07T18:51:40.438Z",
                "client_inet_address": "66.90.249.23",
                "client_country_code": "US",
                "client_location": "30.2966,-97.7663",
                "caller_inet_address": "66.90.249.23",
                "caller_country_code": "US",
                "caller_location": "30.2966,-97.7663"
            },
            "modified": {
                "user": "ANONYMOUS",
                "timestamp": "2018-06-07T18:51:40.686Z",
                "client_inet_address": "66.90.249.23",
                "client_country_code": "US",
                "client_location": "30.2966,-97.7663",
                "caller_inet_address": "66.90.249.23",
                "caller_country_code": "US",
                "caller_location": "30.2966,-97.7663"
            },
            "amount": 10000,
            "unallocated_amount": 0,
            "transaction_id": "mUoM7yoaTvakqPQTvn7KJw",
            "payment_type": "credit_card",
            "contact_id": "p_tup7e7S0e7LIE55qvgXAR",
            "contact": {
                "id": "p_tup7e7S0e7LIE55qvgXAR",
                "test_mode": false,
                "owner_id": "org_Y2eJHCXVqjMlXL9EfmBfc",
                "preferred_email": "eripley@example.com",
                "first_name": "Ellen",
                "last_name": "Ripley",
                "sort_name": "Ripley Ellen",
                "name": "Ellen Ripley",
                "type": "person",
                "display_name": "Ellen Ripley"
            },
            "owner_id": "org_Y2eJHCXVqjMlXL9EfmBfc",
            "card_type": "AMERICAN_EXPRESS",
            "last4_digits": "0005",
            "currency": "USD",
            "bank_account_id": "bank_eZX3KANx7JyXDCrMQkdLj",
            "bank_name": "Chase",
            "bank_account": *****1234",
            "bank_account_type": "operating",
            "status": "authorized",
            "test_mode": true,
            "invoices": [
                {
                    "id": "i_cLjm1bsfOjWs1ekvZmTmU",
                    "invoice_date": "2018-06-06T00:00:00.000Z",
                    "status": "paid",
                    "invoice_number": "000026",
                    "currency": "USD",
                    "type": "invoice"
                }
            ],
            "direction": "inbound",
            "type": "payment"
        }
    ]
}

  

Object Types

All request and response content in this API use JSON representations for serialization to and from the server. The following sections detail the properties, data types, and constraints of each of the types present in the API.

  • Boolean. Boolean values are represented using the JSON literal values true and false
  • Date. Date values (with no time component) are represented using the format yyyy-mm-dd
  • Timestamp. All timestamps sent or received by the Gateway use the ISO-8601 format yyyy-MM-dd'T'HH:mm:ss.SSS'Z', including fractional milliseconds, relative to the UTC time zone. For example, the timestamp 2016-08-21T15:32:21.702Z represents an occurrence on August 21, 2016 at 3:32:21.702 PM UTC.

BankAccount

A payment method that specifies payment details. (ID prefix = bank_)

ParameterTypeDescription
messagesArray of MessageIssues or general messages that occur during the request are communicated through this object. (optional, ignored in request)
idXIDThe ID of the resource. (optional)
nameStringA personalized description of the bank account. (required)
aliasStringA nickname for the bank account. (optional)
bank_nameStringThe official name of the bank where the account is located. (required)
trustBooleanWhether this bank account is a trust account. (required)
account_idStringThe masked digits of the end of the bank account. (required)
testBooleanWhether this is a test bank account. The default is false. (optional)
currencyString3-letter ISO currency code identifying the currency used for the account.
processing_accountsArray of processing_accountThe processing accounts associated with the account. (See merchant_account for details about these parameters.)

Invoice

An invoice. (ID prefix = i_)

ParameterTypeDescription
messagesArray of MessageIssues or general messages that occur during the request are communicated through this object. (optional, ignored in request)
typeStringThe resource type, which is used to identify objects when they share the same endpoint. (optional, unmodifiable, always in response)
idXIDThe ID of the resource. The length must be 21-26 characters. The value must match the pattern ^([a-z][a-z0-9]{0,3}_)?[0-9A-Za-z]{21}$. (optional, ignored in request, always in response)
createdAuditTraceThe date and time when the resource was created. This field cannot be updated. (optional, ignored in request, always in response)
modifiedAuditTraceThe date and time when the resource was last modified. (optional, ignored in request, always in response)
statusStringThe current status of the invoice. The length must be 1-64 characters. (optional, always in response)

One of:

  • draft (default)
  • pending
  • paid
  • void
  • rolled_over
  • write_off
revision_idStringThe current version of the invoice. (optional, always in response)
invoice_numberStringThe number shown on the invoice to identify it.The length must be 1-64 characters. (optional, always in response)
presentment_statusStringThe current status of the invoice: sent (the user has been informed about the invoice creation), failed (the invoice wasn't sent), viewed (the contact has viewed the invoice), or paid (the invoice has been paid). The length must be no more than 20 characters. (optional, ignored in request, always in response, unmodifiable)

One of:

  • sent
  • viewed
  • paid
  • failed
referenceStringMiscellaneous information about the invoice. The length must be no more than 256 characters. (optional)
invoice_datedatetimeThe date and time when the invoice was created. In a request, this can be submitted as just the date, such as 2018-07-21. (required)
due_datedatetimeThe date and time when the invoice is due. (optional)
total_amountIntegerThe sum of all line items in the invoice. This is a generated value. (optional, ignored in request, always in response, unmodifiable)
total_amount_dueIntegerThe amount that remains to be paid on the invoice, taking into account all previous payments. (optional, ignored in request, always in response, unmodifiable)
amount_paidIntegerThe amount already paid toward the invoice. (optional, ignored in request, always in response, unmodifiable)
deletedBooleanWhether the invoice was deleted. The default value is false. (optional, ignored in request, unmodifiable)
test_modeBooleanWhether the invoice is only used for testing. This must be set to true if you're using a test bank account. Contact support@affinipay.com if you are unsure whether your bank account is a test account or a live account. The default value is false. (optional, ignored in request, always in response, unmodifiable)
currencyStringThe ISO 4217 code for the currency used for invoice charges. The length must be no more than 3 characters. (required, always in response)
bank_account_idXIDThe bank account where invoice fees will be deposited (or charged, in case of a credit invoice). The length must be 21-26 characters. The value must match the pattern ^([a-z][a-z0-9]{0,3}_)?[0-9A-Za-z]{21}$. (required, always in response)
owner_idXIDThe ID of the merchant contact who owns the invoice. The length must be 21-26 characters. The value must match the pattern ^([a-z][a-z0-9]{0,3}_)?[0-9A-Za-z]{21}$. (optional, always in response)
contact_idXIDThe ID of the contact who is being invoiced.The length must be 21-26 characters. The value must match the pattern ^([a-z][a-z0-9]{0,3}_)?[0-9A-Za-z]{21}$. (required, always in response)
contactSparse version of the ContactThe contact associated with the invoice. (optional, ignored in request, always in response, unmodifiable)
invoice_paymentsArray of InvoicePaymentThe payments that have been applied to the invoice. (optional, always in response)
itemsDeprecated
line_itemsArray of LineItemThe invoice line items, which define charges associated with the invoice. (optional, always in response)
invoice_messagesArray of InvoiceMessageThe messages sent about the invoice. (optional, always in response)
attachmentsArray of FileReferenceFiles attached to the invoice. In a request, this is an array of attachment id, each with an fref_ prefix (optional, always in response)
source_idStringThe URI that uniquely identifies an invoice in the caller's environment. Attempts to create another invoice with the same source_id will result in an HTTP 409 with error code “resource_exists”. (optional, maximum length is 255 characters, write-only, must be unique to calling merchant) (optional)
notesStringExtra details about the object. (optional, maximum length is 1024 characters)

InvoiceMessage

An invoice message, which is delivered via email. (ID prefix = imsg_)

ParameterTypeDescription
messagesArray of MessageIssues or general messages that occur during the request are communicated through this object. (optional, ignored in request)
typeStringThe resource type, which is used to identify objects when they share the same endpoint. (optional, unmodifiable, always in response)
idXIDThe ID of the resource. The length must be 21-26 characters. The value must match the pattern ^([a-z][a-z0-9]{0,3}_)?[0-9A-Za-z]{21}$. (optional, ignored in request, always in response)
createdAuditTraceThe date and time when the resource was created. This field cannot be updated. (optional, ignored in request, always in response)
modifiedAuditTraceThe date and time when the resource was last modified. (optional, ignored in request, always in response)
email_addressesArray of StringThe email addresses where the invoice message was sent. (required)
subjectStringThe subject of the email; when specified in a request, it overwrites the default subject, which is "Your AffiniPay Invoice" and the invoice number. The length must be no more than 256 characters. (optional)
bodyStringThe body of the email. (optional, ignored in request, always in response)
messageStringThe invoice message that was included in the email. (optional)
statusStringThe status of the email. (optional, always in response)

One of:

  • sent
  • failed_to_send

InvoicePayment

An invoice payment. (ID prefix = ipmt_)

ParameterTypeDescription
messagesArray of MessageIssues or general messages that occur during the request are communicated through this object. (optional, ignored in request)
typeStringThe resource type, which is used to identify objects when they share the same endpoint. (optional, unmodifiable, always in response)
idXIDThe ID of the resource. The length must be 21-26 characters. The value must match the pattern ^([a-z][a-z0-9]{0,3}_)?[0-9A-Za-z]{21}$. (optional, ignored in request, always in response)
createdAuditTraceThe date and time when the resource was created. This field cannot be updated. (optional, ignored in request, always in response)
modifiedAuditTraceThe date and time when the resource was last modified. (optional, ignored in request, always in response)
amountIntegerThe amount that was paid toward the invoice. (required)
directionStringWhether the invoice is for a charge (inbound) or a credit (outbound). (required)

One of:

  • inbound
  • outbound

LineItem

An invoice line item.

ParameterTypeDescription
idStringThe UUID of the line item, stored as a base64 string. (optional, ignored in request, always in response)
codeStringA code that can identify this item to external systems. The length must be no more than 64 characters. (optional)
descriptionStringA description of the line item. The length must be 1-256 characters. (required)
rate_per_quantityBigDecimalStringThe amount charged per unit. (required)
quantityBigDecimalStringThe number of units to be charged. (required)
rate_typeStringThe units used to measure the rate to be charged for the item. (required)

One of:

  • percentage
  • hours
  • units

Payment

A payment applied to an invoice. (ID prefix = pmt_)

ParameterTypeDescription
messagesArray of MessageIssues or general messages that occur during the request are communicated through this object. (optional, ignored in request)
typeStringThe resource type, which is used to identify objects when they share the same endpoint. (optional, unmodifiable, always in response)
idXIDThe ID of the resource. The length must be 21-26 characters. The value must match the pattern ^([a-z][a-z0-9]{0,3}_)?[0-9A-Za-z]{21}$. (optional, ignored in request, always in response)
createdAuditTraceThe date and time when the resource was created. This field cannot be updated. (optional, ignored in request, always in response)
modifiedAuditTraceThe date and time when the resource was last modified. (optional, ignored in request, always in response)
directionStringWhether the payment is for a charge (inbound) or a credit (outbound). (required)

One of:

  • inbound
  • outbound
amountIntegerThe amount of the payment. The value must be at least 0. (required)
unallocated_amountIntegerThe amount that hasn't been linked to an invoice payment yet. The value must be at least 0. (required)
transaction_idTransactionIdThe transaction ID, used to link charges and credits on the Gateway. (optional)
payment_typePaymentTypeThe type of payment used. (required)

One of:

  • bank_account
  • cash
  • check
  • credit_card
  • other
contact_idXIDThe ID of the contact who made the payment. The length must be 21-26 characters. The value must match the pattern ^([a-z][a-z0-9]{0,3}_)?[0-9A-Za-z]{21}$. (required)
contactSparse version of the ContactThe contact who made the payment. (optional, ignored in request, always in response)
owner_idXIDThe ID of the merchant or tenant contact who is being paid. The length must be 21-26 characters. The value must match the pattern ^([a-z][a-z0-9]{0,3}_)?[0-9A-Za-z]{21}$. (required)
card_typeStringThe type of credit card used. (optional)

One of:

  • MASTERCARD
  • VISA
  • AMERICAN_EXRESS
  • DISCOVER
  • DINERS_CLUB
  • JCB
  • UNKNOWN
last4_digitsStringThe last four digits of the credit card used. (For credit card payments only.) (optional)
currencyStringThe ISO 4217 code for the currency used for payment. The length must be no more than 3 characters. (required)
bank_account_idXIDThe bank account where invoice fees will be deposited (or charged, in case of a credit invoice). The length must be 21-26 characters. The value must match the pattern ^([a-z][a-z0-9]{0,3}_)?[0-9A-Za-z]{21}$. (required)
bank_nameStringThe official name of the bank. (optional)
bank_accountStringThe masked last digits of the merchant's bank account. (optional)
bank_account_typeStringThe type of bank account used. (optional)

One of:

  • operating
  • iolta
bank_account_aliasStringA personalized name for the merchant's bank account. (optional)
statusStringThe current status of the payment. (required)

One of:

  • completed
  • authorized
  • pending
  • transaction_failed
  • submission_failed
  • voided
failure_messageStringIf the payment failed, the reason why it failed. (optional)
test_modeBooleanWhether this payment is a test payment. The default value is false. (required)
referenceStringMiscellaneous information about the invoice. The length must be no more than 256 characters. (optional)
invoicesArray of sparse versions of InvoiceThe invoices that were paid by this payment. (required)
failure_email_addressesArray of StringThe email addresses where failure messages are sent. (optional)

PaymentRequest

A payment applied to an invoice. (ID prefix = pmt_)

ParameterTypeDescription
token_idStringThe ID of the payment token used to create a transaction on the gateway. Either a token_id or a payment_method_id is required for gateway transactions.
payment_method_idXIDThe ID of the payment method used to create a transaction on the gateway. Either a token_id or a payment_method_id is required for gateway transactions.
payment_typePaymentTypeThe type of payment used. If a token_id or payment_method_id is not used or if a payment is made outside the gateway, the payment_type is required.

One of:

  • bank_account
  • cash
  • check
  • credit_card
  • other
directionStringWhether the payment is for a deposit (inbound) or a withdrawl (outbound) from the bank_account. The default value is inbound. (optional)

One of:

  • inbound
  • outbound
amountIntegerThe amount of the payment. The value must be at least 1. (required)
currencyStringThe ISO 4217 code for the currency used for payment. The length must be no more than 3 characters. (required)
referenceStringMiscellaneous information about the invoice. The length must be no more than 256 characters. (optional)
scheduled_run_timedatetimeThe date and time when the payment will be run, if in the future. (optional)
receipt_email_addressesArray of StringThe email addresses where the payment receipt will be sent. (optional)
invoice_idsArray of XIDThe IDs of the invoices to be paid. (optional)