Use this API to gain authorized access to AffiniPay merchant accounts.
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.
Parameter | Description |
---|---|
client_id | A unique 64-character, alphanumeric string used to identify your partner OAuth application in OAuth 2.0 web flows. |
client_secret | A unique 64-character, alphanumeric string used to authenticate your partner OAuth application in OAuth 2.0 web flows. |
grant_type | Specifies which grant type to use in the OAuth 2.0 web flow. Set this to authorization_code. |
scope | Determines the level of access your partner OAuth application has to the merchant's account. Set this to payments. |
redirect_uri | Per 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. |
code | The 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
}
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": []
}
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.
Parameter | Description |
---|---|
public_key | A unique 24-character, alphanumeric string used to identify AffiniPay merchant accounts. |
access_token | A 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.
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.
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.
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"
}
}
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.
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.
Parameter | Type | Description |
---|---|---|
reference | string | The unique ID for the user in the partner's system. |
string | The user's email. | |
plan | string | The 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.
Parameter | Type | Description |
---|---|---|
first_name | string | First name of the person associated with the merchant application. |
last_name | string | Last name of the person associated with the merchant application. |
business_name | string | The business's legal name. This must match what is on record with the IRS. |
business_address1 | string | The business's mailing address. |
business_address2 | string | Additional address field. |
business_city | string | The city where the business is located. |
business_state | string | The state where the business is located. |
business_zip_code | string | The business's postal ZIP code. |
business_phone | string | The business's primary contact number. |
business_country | string | The 2-letter ISO 3166 country code for the country where the business is located. |
industry_code | integer | The business's Standard Industrial Classification (SIC) code (e.g., 8111 – Legal Services). |
goods_and_services | string | Send "Legal Fees" for a LawPay integration. Contact AffiniPay for the correct string to use for other integrations. |
has_dba | boolean | Indicates whether a Doing Business As (DBA) name has been registered for the business; default is false (optional). |
dba_name | string | The business's registered Doing Business As (DBA) name (optional if has_dba is false). |
dba_address1 | string | The mailing address of the business with a registered Doing Business As (DBA) name (optional if has_dba is false). |
dba_address2 | string | Additional address field (optional if has_dba is false). |
dba_city | string | The city where the business with a registered Doing Business As (DBA) name is located (optional if has_dba is false). |
dba_state | string | The 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_code | string | The postal ZIP code of the business with a registered Doing Business As (DBA) name (optional if has_dba is false). |
dba_phone | string | The primary contact number of the business with a registered Doing Business As (DBA) name (optional if has_dba is false). |
structure | string | The business's structure. Accepts a 1- or 2-letter abbreviation. Only include the abbreviation in the request, not the description (e.g., SO):
|
business_type | string | The 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):
|
years_in_business | string | Number years the business has been in operation. |
business_website | string | The business's website (optional). |
past_bankruptcy | boolean | Indicates whether the business has been through bankruptcy proceedings in the past (optional). |
bankruptcy_date | date | The date the bankruptcy was finalized (optional). |
owner_first_name | string | The business owner's legal first name. |
owner_last_name | string | The business owner's legal last name. |
owner_title | string | The business owner's title. Accepts the following values (no spaces):
|
owner_percentage_of_ownership | integer | The business owner's percentage of ownership (optional, defaults to 100). |
owner_has_significant_ownership | Boolean | Whether the business owner has more than 25% ownership of the business. |
owner_has_significant_responsibility | Boolean | Whether 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_address1 | string | The business owner's mailing address. |
owner_address2 | string | Additional address field. |
owner_city | string | The city where the business owner lives. |
owner_state | string | The state where the business owner lives. |
owner_zip_code | string | The business owner's postal ZIP code. |
owner_phone_number | string | The business owner's primary contact number. |
owner_email | string | The business owner's email address. |
owner_years_in_residence | integer | The number of years the business owner has resided at owner_address1 (optional). |
owner_country_of_citizenship | string | The 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...>"
}
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.
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.
Parameter | Type | Description |
---|---|---|
reference | string | This 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>) |
plan | string | The identifier for your plan within the AffiniPay system. We will create this plan for you and provide you the correct ID to use. |
first_name | string | First name of the person associated with the merchant application. |
last_name | string | Last name of the person associated with the merchant application. |
string | Email address of the person associated with the merchant application. | |
business_name | string | The business's legal name. This must match what is on record with the IRS. |
business_address1 | string | The business's mailing address. |
business_address2 | string | Additional address field. |
business_city | string | The city where the business is located. |
business_state | string | The state where the business is located. |
business_zip_code | string | The business's postal ZIP code. |
business_phone | string | The business's primary contact number. |
business_country | string | The 2-letter ISO 3166 country code for the country where the business is located. |
industry_code | integer | The business's Standard Industrial Classification (SIC) code (e.g., 8111 – Legal Services). |
goods_and_services | string | Send "Legal Fees" for a LawPay integration. Contact AffiniPay for the correct string to use for other integrations. |
has_dba | boolean | Indicates whether a Doing Business As (DBA) name has been registered for the business; default is false (optional). |
dba_name | string | The business's registered Doing Business As (DBA) name (optional if has_dba is false). |
dba_address1 | string | The mailing address of the business with a registered Doing Business As (DBA) name (optional if has_dba is false). |
dba_address2 | string | Additional address field (optional if has_dba is false). |
dba_city | string | The city where the business with a registered Doing Business As (DBA) name is located (optional if has_dba is false). |
dba_state | string | The 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_code | string | The postal ZIP code of the business with a registered Doing Business As (DBA) name (optional if has_dba is false). |
dba_phone | string | The primary contact number of the business with a registered Doing Business As (DBA) name (optional if has_dba is false). |
structure | string | The business's structure. Accepts a 1- or 2-letter abbreviation. Only include the abbreviation in the request, not the description (e.g., SO):
|
business_type | string | The 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):
|
federal_tax_id | string | The 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_business | string | Number years the business has been in operation. |
business_website | string | The business's website (optional). |
past_bankruptcy | boolean | Indicates whether the business has been through bankruptcy proceedings in the past (optional). |
bankruptcy_date | date | The date the bankruptcy was finalized (optional). |
owner_first_name | string | The business owner's legal first name. |
owner_last_name | string | The business owner's legal last name. |
owner_title | string | The business owner's title. Accepts the following values (no spaces):
|
owner_date_of_birth | date | The business owner's date of birth. |
owner_social_security_number | string | The business owner's Social Security Number (SSN); used for credit check. |
owner_percentage_of_ownership | integer | The business owner's percentage of ownership (optional, defaults to 100). |
owner_has_significant_ownership | Boolean | Whether the business owner has more than 25% ownership of the business. |
owner_has_significant_responsibility | Boolean | Whether 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_address1 | string | The business owner's mailing address. |
owner_address2 | string | Additional address field. |
owner_city | string | The city where the business owner lives. |
owner_state | string | The state where the business owner lives. |
owner_zip_code | string | The business owner's postal ZIP code. |
owner_phone_number | string | The business owner's primary contact number. |
owner_email | string | The business owner's email address. |
owner_years_in_residence | integer | The number of years the business owner has resided at owner_address1 (optional). |
owner_drivers_license_number | string | The business owner's driver's license number; used to verify identity. |
owner_drivers_license_state | string | The state that issued the business owner's driver's license (two-letter state code). |
owner_drivers_license_expiration | date | The business owner's driver's license expiration date. |
owner_country_of_citizenship | string | The 2-letter ISO 3166 country code for the country where the business owner resides. |
operating_account_name | string | The name of the business's operating account (optional). |
operating_account_routing_number | string | The routing number of the business's operating account. |
operating_account_bank_name | string | The name of the bank where the business holds an operating account. |
operating_account_number | string | The business's operating account number. |
trust_account_name | string | The name of the business's trust account (optional). |
trust_account_routing_number | string | The 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_name | string | The 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_number | string | The business's trust account number; optional unless plan is a trust plan (optional unless plan is a trust plan). |
signed_by | string | The name of a business representative who's authorized to sign the merchant application; optional unless plan is a trust plan. |
signature | string | The 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_address | string | The 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_agent | string | The 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_language | string | The 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_timestamp | timestamp | The signature timestamp, collected at signature time. |
test | string | Defines 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) |
Parameter | Type | Description |
---|---|---|
first_name | string | First name of business owner. |
last_name | string | Last name of business owner. |
home_address1 | string | The business owner's mailing address. |
home_address2 | string | Additional address information (optional). |
home_city | string | The business owner's city. |
home_state | string | The business owner's state. |
home_zip_code | string | The business owner's postal ZIP code. |
job_title | string | The business owner's title. Accepts the following values (no spaces):
|
date_of_birth | date | The business owner's date of birth. |
social_security_number | string | The business owner's Social Security Number (SSN); used for credit check. |
has_significant_ownership | Boolean | Whether the business owner has more than 25% ownership of the business. |
has_significant_responsibility | Boolean | Whether 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. |
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"
}
]
}
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.
Configuring webhooks requires two components:
To specify where you want AffiniPay to send events:
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.
This section describes event types that the Merchant Application API generates.
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>"
}
}]
}
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>"
}
}]
}
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.
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.
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.
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" ...
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 Code | Description |
---|---|
200 | The operation succeeded |
204 | The operation succeeded, but no response content was returned (normal for APIs that do not return any JSON response) |
400 | The request was malformed |
401 | Authentication credentials were not provided, or were not valid for the requested operation |
404 | An item referred to in the request, such as a charge or merchant bank account, was not found |
422 | The request could not be processed. This is typically due to validation errors reported in the response. |
500 | An error occurred on the Gateway while processing the request |
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.
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 Number | Card Type |
---|---|
378282246310005 | American Express |
371449635398431 | American Express |
5105105105105100 | MasterCard |
5499740000000057 | MasterCard |
30569309025904 | Diners Club |
38520000023237 | Diners Club |
6011000990139424 | Discover |
3530111333300000 | JCB |
3566002020360505 | JCB |
4242424242424242 | Visa |
4012888888881881 | Visa |
4400000000000008 | Visa Debit |
Failure scenarios can be tested using the following card numbers and the test-mode secret key:
Card Number | Error Code |
---|---|
4000000000000002 | card_declined |
4000000000000044 | card_declined_insufficient_funds |
4000000000000051 | card_declined_limit_exceeded |
4000000000000069 | card_expired |
4000000000000119 | card_declined_processing_error |
4000000000000127 | card_declined_hold |
4242424242424241 | card_number_invalid |
4000000000000135 | card_type_not_accepted |
6011111111111117 | 503 PROCESSOR NOT AVAILABLE |
5555555555554444 | 500 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 Number | CVV/AVS Response |
---|---|
4000000000000077 | CVV Unavailable |
4000000000000101 | CVV Not Matched |
4000000000000010 | AVS Not Matched |
4000000000000085 | AVS Unavailable |
4000000000000093 | AVS Error |
4000000000000028 | If card postal code is null or empty, AVS returns Not Matched. Otherwise, an AVS Postal Code Match is returned. |
4000000000000036 | If card address is null or empty, AVS returns Not Matched. Otherwise an AVS Address Match is returned. |
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 Number | Account Number | Error Code |
---|---|---|
000000013 | 1000000001 | ach_declined |
000000013 | 1000000002 | ach_declined_hold |
000000013 | 1000000003 | ach_declined_duplicate |
000000013 | 1000000004 | ach_invalid_account_number |
000000013 | 1000000005 | ach_insufficient_funds |
000000013 | 1000000006 | ach_account_not_found |
000000013 | 1000000007 | ach_account_closed |
000000013 | 1000000008 | ach_account_frozen |
000000013 | 1000000009 | ach_limit_exceeded |
000000001 | Any | ach_invalid_routing_number |
000000013 | 1000000004 | 422 INVALID ACCOUNT NUMBER |
000000013 | 1000000011 | 503 ACH PROCESSOR NOT AVAILABLE |
000000013 | 1000000012 | 500 SERVER ERROR |
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.
Status | Description |
---|---|
NORMAL | The gateway is functioning normally. |
EXCESSIVE_LATENCY | API request durations are exceeding expected thresholds. |
SERVICE_UNRELIABLE | Recent intermittent failures are impacting payment processing. |
SERVICE_UNAVAILABLE | The system us experiencing problems that prevent payment processing. |
Example Request
curl https://api.affinipay.com/status
Example Response
{
"status":"NORMAL"
}
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 /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"
}
]
}
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": [
...
]
}
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"
}
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.
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.
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"
}
}
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"
}
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:
Parameter | Type | Description |
---|---|---|
description | String | Description to be applied to the recurring charge (optional) |
amount | Integer | The 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_unit | String | The interval unit of the schedule. Enumeration of:
|
interval_delay | Number | The 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. |
end | Date | The end date for the schedule such that the last occurrence is executed on or before this date (optional). |
days | Array of String | Schedules 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_occurrences | Number | The 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_amount | Number | The 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"
}
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:
Parameter | Type | Description |
---|---|---|
amount | Integer | The recurring amount to charge, in terms of the currency's smallest unit. For USD, this is the amount in cents. |
schedule | Schedule | The schedule indicating when payments are due. The following properties are required:
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 /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:
The following URI parameter is required:
Parameter | Description |
---|---|
bank_account_id | The system-generated ID of a bank account. (required) |
The following query parameter is optional:
Parameter | Type | Description |
---|---|---|
amount | Number | The 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
}
]
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:
Parameter | Type | Description |
---|---|---|
amount | Integer | The 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. |
reference | String | A reference to be applied to the transaction for the capture operation (optional, maximum length is 128 characters) |
capture_time | String | When 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:
|
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
}
}
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:
Parameter | Description |
---|---|
page | The page number to view, starting from 1 (optional, defaults to 1) |
page_size | The number of results to return per logical page (optional, defaults to 20, max is 100) |
account_id | If 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"
} ]
}
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"
}
}
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:
Parameter | Type | Description |
---|---|---|
reference | String | A 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"
}
}
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"
}
}
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 /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 /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 /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"
}
}
]
}
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:
Parameter | Description |
---|---|
page | The page number to view, starting from 1 (optional, defaults to 1) |
page_size | The number of results to return per logical page (optional, defaults to 20, max is 100) |
q | A 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) |
qf | A 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_date | Only 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_date | Only 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_id | If specified, only transactions processed through the specified account are returned; if omitted, transactions are returned associated with all of the Merchant's accounts. |
order_by | A 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",
...
}
}
]
}
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:
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:
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 /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"
}
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"
}
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 /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",
...
}
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:
Parameter | Description |
---|---|
page | The page number to view, starting from 1 (optional, defaults to 1) |
page_size | The number of results to return per logical page (optional, defaults to 20, max is 100) |
account_id | If 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. |
status | The 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. |
reference | If specified, only recurring charges having a matching reference are returned. |
order_by | A 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",
...
}
]
}
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
Parameter | Type | Description |
---|---|---|
occurrences | String | The number of occurrences for the recurring charge. The default is 10. The maximum is 100. |
start_date | Date | The 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_charge | Boolean | Whether 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 /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"
} ]
}
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"
} ]
}
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
}
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:
Parameter | Description |
---|---|
page | The page number to view, starting from 1 (optional, defaults to 1) |
page_size | The 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"
} ]
} ]
}
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.
Merchant systems can use the saved card APIs to provide secure storage of "remembered" credit cards for a customer for use in future transactions.
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
}
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 /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 /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
}
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:
Parameter | Description |
---|---|
page | The page number to view, starting from 1 (optional, defaults to 1) |
page_size | The number of results to return per logical page (optional, defaults to 20, max is 100) |
reference | Returns only Cards having the given reference value (optional) |
exp_month | Returns Cards for which the expiration month matches the given value (optional) |
exp_year | Returns Cards for which the expiration year matches the given value (optional) |
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
}
]
}
The saved bank object provides functionality for merchant systems to securely store "remembered" bank information for use as payment methods in the Transactions endpoints.
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"
}
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 /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 /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"
}
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:
Parameter | Description |
---|---|
page | The page number to view, starting from 1 (optional, defaults to 1) |
page_size | The number of results to return per logical page (optional, defaults to 20, max is 100) |
reference | Returns 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"
}
]
}
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.
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 /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"
}
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:
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 /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" : "***"
}
}
}
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.
Parameter | Description |
---|---|
page | The page number to view, starting from 1 (optional, defaults to 1) |
page_size | The number of results to return per logical page (optional, defaults to 20, max is 1000) |
start_date | Only 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",
...
}
]
}
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.
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.
Parameter | Type | Description |
---|---|---|
id | String | The ID of the entity (read-only) |
created | Timestamp | Date/time the entity was created (read-only) |
modified | Timestamp | Date/time the entity was last modified (read-only) |
messages | Array of Strings | Validation or warning messages associated with an operation requested on this entity (read-only) |
trust_account | Boolean | Whether or not this is a trust account. If unknown, the property is not returned (read-only) |
status | String | Status of the bank account (read-only). Enumeration of:
|
name | String | Descriptive name for the account, for display purposes only |
primary | Boolean | Whether 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_number | String | 9-digit routing number of the merchant's bank |
account_number | String | Merchant's bank account number. The value may be 4-17 digits, with no punctuation or other characters. |
account_type | String | The type of the merchant bank account specified, either checking or savings . Enumeration of:
|
bank_name | String | Name 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_fields | String | Comma-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:
|
transaction_allowed_countries | String | Comma-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) |
currency | String | 3-letter ISO currency code identifying the currency used for the account. |
Provides details for a customer and bank account for use in payment methods.
Parameter | Type | Description |
---|---|---|
id | String | The ID of the entity (read-only) |
created | Timestamp | Date/time the entity was created (read-only) |
modified | Timestamp | Date/time the entity was last modified (read-only) |
type | String | The type of the payment method. For bank details, this is always bank. |
token_id | String | ID of a one-time payment token from which to create the Bank (optional) |
routing_number | String | 9-digit routing number of the customer's bank |
account_number | String | Customer's bank account number. The value may be 4-17 digits, with no punctuation or other characters. |
account_type | String | The type of the customer bank account specified, either checking or savings. Enumeration of:
|
bank_name | String | Name 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) |
fingerprint | String | A 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_type | String | The type of account holder, either individual or business (default is business) |
name | String | Business name (required for business account_holder_type, ignored for individual account_holder_type) |
given_name | String | The 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) |
surname | String | The 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) |
address1 | String | Customer address (optional) |
address2 | String | Additional address line (optional) |
city | String | Customer city (optional) |
state | String | Customer state. For US and Canada, this must be the 2-letter state or province code. (Optional) |
postal_code | String | Customer 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) |
country | String | Customer 2-letter ISO 3166 country code (optional) |
String | Customer email address (optional) | |
phone | String | Customer phone number. No specific format is required, but the total length cannot exceed 22 characters. (Optional) |
reference | String | A 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) |
description | String | Description for the bank details, limited to 64 characters. Only used when creating a saved Bank instance. (Optional) |
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.
Parameter | Type | Description |
---|---|---|
id | String | The ID of the entity (read-only) |
created | Timestamp | Date/time the entity was created (read-only) |
modified | Timestamp | Date/time the entity was last modified (read-only) |
type | String | The type of the payment method. For card details, this is always card. |
token_id | String | ID of a one-time payment token from which to create the Card (optional) |
number | String | The credit card number (required unless track1 or track2 stripe data is provided, in which case the value is ignored) |
fingerprint | String | A 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_type | String | Type of the credit card (optional). Enumeration of:
|
exp_month | Number, 1-12 | Card expiration month (required unless track1 or track2 stripe data is provided, in which case the value is ignored) |
exp_year | Number | 2 or 4-digit card expiration year (required unless track1 or track2 stripe data is provided, in which case the value is ignored) |
cvv | String | Card CVV (optional) |
track1 | String | Card 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). |
track2 | String | Card 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). |
name | String | Card holder name (optional) |
address1 | String | Card holder address (optional) |
address2 | String | Additional card holder address line (optional) |
city | String | Card holder city (optional) |
state | String | Card holder state. For US and Canada, this must be the 2-letter state or province code. (Optional) |
postal_code | String | Billing 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) |
country | String | Card holder 2-letter ISO 3166 country code (optional) |
String | Customer email address (optional) | |
phone | String | Customer phone number. No specific format is required, but the total length cannot exceed 22 characters. (Optional) |
reference | String | A 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) |
description | String | Description for the card details, limited to 64 characters. Only used when creating a saved Card instance. (Optional) |
status | String | Whether 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. |
A credit card charge.
Parameter | Type | Description |
---|---|---|
id | String | The ID of the entity (read-only) |
source_id | String | The 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) |
created | Timestamp | Date/time the entity was created (read-only) |
modified | Timestamp | Date/time the entity was last modified (read-only) |
messages | Array of Strings | Validation or warning messages associated with an operation requested on this entity (read-only) |
type | String | Type of the transaction, used to differentiate Charges and Refunds in transaction search results. For Charges, the value is always CHARGE. (read-only) |
account_id | String | The ID of the account to receive payment from the Charge (set at creation of the Charge, read-only thereafter) |
status | String | Status of the transaction (read-only). Enumeration of:
|
completion_timestamp | datetime | The date and time when the transaction was COMPLETED. If the status is not COMPLETED, this field is null. (read-only) |
failure_code | String | Failure 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. |
amount | Number | The 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_amount | Number | The 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 |
currency | String | 3-letter ISO 4217 code representing the currency in which the amount is denominated (optional, defaults to USD) |
method | Payment method or ID | Details 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). |
data | JSON hash | A JSON hash containing any additional data to be included on the transaction. Storage charges may apply based on the amount of data saved. |
auto_capture | Boolean | Whether 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_refunded | Number | The total amount refunded from the authorized amount |
authorization_code | String | The 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_result | String | CVV result from authorization of the Charge, if any (read-only). Enumeration of:
|
avs_result | String | AVS result from authorization of the Charge, if any (read-only). Enumeration of:
|
reference | String | An 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_reference | String | An 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_reference | String | An optional reference provided by the Merchant when voiding the transaction. Maximum length is 128 characters. |
recurring_charge_id | String | The ID of the RecurringCharge instance if the transaction was performed in the context of a recurring payment (read-only) |
recurring_charge_ occurrence_id | String | The ID of the associated occurrence of the recurring payment, if any. This property is only set if recurring_charge_id is defined. (Read-only) |
refunds | Array of refunds | Subsequent refunds applied to the Charge (read-only) |
A Credit returns funds to the customer card or bank provided in the payment method, without requiring a parent Charge.
Parameter | Type | Description |
---|---|---|
id | String | The ID of the entity. (read-only) |
source_id | String | A 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) |
created | Timestamp | Date/time the entity was created. (read-only) |
modified | Timestamp | Date/time the entity was last modified. (read-only) |
messages | Array of Strings | Validation or warning messages associated with an operation requested on this entity. (read-only) |
type | String | Type of the transaction, used to differentiate Charges, Refunds, and Credits in transaction search results. For Credits, the value is always CREDIT. (read-only) |
account_id | String | The ID of the account to receive payment from the Charge. (set at creation of the Charge, read-only thereafter) |
status | String | Status of the credit (read-only). Enumeration of:
|
completion_timestamp | datetime | The date and time when the transaction was COMPLETED. If the status is not COMPLETED, this field is null. (read-only) |
failure_code | String | Failure 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. |
amount | Number | The 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. |
currency | String | 3-letter ISO 4217 code representing the currency in which the amount is denominated. (optional, defaults to USD) |
auto_capture | Boolean | Whether or not the Credit will be automatically captured by the Gateway. At present, this value is always true. (Read-only) |
method | Payment method or ID | Details 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). |
data | JSON hash | A JSON hash containing any additional data to be included on the credit. Storage charges may apply based on the amount of data saved. |
auto_capture | Boolean | Whether the Credit will be automatically captured by the Gateway. At present, this is always true. |
reference | String | An 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_reference | String | An optional reference provided by the Merchant when canceling the credit. Maximum length is 128 characters. |
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.
Parameter | Type | Description |
---|---|---|
id | String | The ID of the entity (read-only) |
created | Timestamp | Date/time the entity was created (read-only) |
type | String | The type of the event (read-only) |
data | JSON hash | The content of the event (read-only) |
A loan.
Parameter | Type | Description |
---|---|---|
id | String | The ID of the entity (read-only) |
created | Timestamp | Date/time the entity was created (read-only) |
modified | Timestamp | Date/time the entity was last modified (read-only) |
givenName | String | The first name of the loanee. Must be 2-40 characters. (read-only) |
surname | String | The last name of the loanee. Must be less than 64 characters. (read-only) |
address1 | String | Loanee address. Must be less than 64 characters. (read-only) |
address2 | String | Additional address line. Must be less than 64 characters. (read-only) |
city | String | Loanee city. Must be less than 64 characters. (read-only) |
state | String | Loanee state. Must be less than 64 characters. (read-only) |
postalCode | String | Loanee zip or postal code. (read-only) |
country | String | Loanee 2-letter ISO 3166 country code. (read-only) |
String | Loanee email address. Must be less than 254 characters. (read-only) | |
phone | String | Loanee phone number. Must be less than 22 characters. (read-only) |
A business which processes payments using associated merchant and eCheck accounts.
Parameter | Type | Description |
---|---|---|
id | String | The ID of the entity (read-only) |
created | Timestamp | Date/time the entity was created (read-only) |
modified | Timestamp | Date/time the entity was last modified (read-only) |
messages | Array of Strings | Validation or warning messages associated with an operation requested on this entity (read-only) |
name | String | Name of the Merchant |
public_key | String | Public identity of the Merchant, used to initialize hosted fields for payment form integration |
contact_name | String | Name of the contact at the Merchant |
contact_email | String | Email address used to contact the Merchant |
contact_phone | String | Phone number used to contact the Merchant, in E-164 format. Leading '+' is optional. |
address1 | String | Mailing address of the Merchant |
address2 | String | Additional address field (optional) |
city | String | City in which the Merchant is located |
state | String | State or province. For US and Canada, this must be the 2-letter state or province code in which the Merchant is located. |
postal_code | String | Merchant 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. |
country | String | 2-letter ISO 3166 country code in which the Merchant's business is located |
timezone | String | Time zone ID associated with the Merchant (e.g., "America/New_York") used for settlement |
merchant_accounts | Array of merchant_account | The merchant's credit Accounts |
ach_accounts | Array of ach_account | The merchant's bank accounts for eCheck transactions |
api_allowed_ip_address_ranges | String | Comma-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_urls | String | Comma-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_urls | String | Comma-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. |
A merchant bank account's parameters, used to interact with payment processors to move funds between the merchant's account and credit card accounts.
Parameter | Type | Description |
---|---|---|
id | String | The ID of the entity (read-only) |
created | Timestamp | Date/time the entity was created (read-only) |
modified | Timestamp | Date/time the entity was last modified (read-only) |
messages | Array of Strings | Validation or warning messages associated with an operation requested on this entity (read-only) |
trust_account | Boolean | Whether or not this is a trust account. If unknown, the property is not returned (read-only). |
status | String | Status of the Account (read-only). Enumeration of:
|
name | String | Descriptive name for the account, for display purposes only |
primary | Boolean | Whether 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. |
currency | String | 3-letter ISO currency code identifying the currency used by the Merchant |
accepted_card_types | String | Comma-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_policy | String | The CVV matching policy applied to non-swiped Charges made through the Account. Enumeration of:
|
avs_policy | String | The address verification policy applied to non-swiped Charges made through the Account. Enumeration of:
|
ignore_avs_failure_if_cvv_match | Boolean | Whether 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_fields | String | Comma-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:
|
swipe_cvv_policy | String | The CVV matching policy applied to retail swiped Charges made through the account. Available property values are identical to cvv_policy. |
swipe_avs_policy | String | The 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_match | Boolean | Whether 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_fields | String | Comma-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_countries | String | Comma-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. |
A recurring charge that automatically attempts to collect payment on a defined schedule.
Parameter | Type | Description |
---|---|---|
id | String | The ID of the entity (read-only) |
source_id | String | The 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) |
created | Timestamp | Date/time the entity was created (read-only) |
modified | Timestamp | Date/time the entity was last modified (read-only) |
messages | Array of Strings | Validation or warning messages associated with an operation requested on this entity (read-only) |
status | String | Status of the recurring charge (read-only). Enumeration of:
|
status_reason | String | Reason code indicating why the recurring charge transitioned to the current status (read-only). Enumeration of:
|
account_id | String | The ID of the account to receive payment from the recurring charge (set at creation of the recurring charge, read-only thereafter) |
method | Payment method or ID | Details 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). |
schedule | Schedule | The 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. |
description | String | Description for the recurring charge (optional) |
amount | Number | The 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. |
currency | String | 3-letter ISO 4217 code representing the currency in which the amount is denominated (optional, defaults to USD) |
reference | String | An optional reference to be set on each Charge created to collect a scheduled payment associated with this recurring charge (optional) |
max_occurrences | Number | The 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_amount | Number | The 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_occurrences | Number | The 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_amount | Number | The 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_payment | Date | The date the Gateway will attempt to collect the next payment, if any scheduled payments remain. |
data | JSON hash | A 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. |
occurrences | Array of recurring_charge_occurrences | The 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) |
An occurrence of a recurring charge. Occurrences track individual scheduled payments as defined by the schedule of the owning recurring_charge.
Parameter | Type | Description |
---|---|---|
id | String | The ID of the entity (read-only) |
source_id | String | The 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) |
created | Timestamp | Date/time the entity was created (read-only) |
modified | Timestamp | Date/time the entity was last modified (read-only) |
recurring_charge_id | String | ID of the owning recurring charge (read-only) |
amount | Number | The amount, in terms of the base unit of the owning recurring charge account's currency, to be collected by this occurrence (read-only) |
status | String | The status of the occurrence (read-only). Enumeration of:
|
due_date | Date | The date the Gateway will attempt to collect payment for the occurrence (read-only) |
attempts | Number | The number of attempts made to collect payment on this occurrence (read-only) |
last_attempt | Timestamp | The last time an attempt was made to collect payment for this occurrence (read-only) |
transactions | Array of charges | The transactions which have attempted to collect payment for this occurrence, in order of increasing creation timestamp (read-only) |
A projection of the occurrences for a recurring charge for a defined schedule.
Parameter | Type | Description |
---|---|---|
amount | Number | The 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_occurrences | Number | The 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_amount | Number | The 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_amount | Number | The 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_occurrences | Number | The 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_occurrences | Number | The total number of occurrences remaining for this recurring charge projection. This can be null if the schedule is boundless. |
remaining_amount | Number | The total amount remaining for this recurring charge projection. This can be null if the schedule is boundless. |
schedule | Schedule | The 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_payment | Date | The date the Gateway will attempt to collect the next payment, if any scheduled payments remain. |
occurrences | Array | The 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) |
An occurrence of a recurring charge projection. Occurrences track individual scheduled payment projections as defined by the schedule of the owning recurring_charge_projection.
Parameter | Type | Description |
---|---|---|
amount | Number | The amount, in terms of the base unit of the owning recurring charge account's currency, to be collected by this occurrence. (read-only) |
due_date | Date | The date the Gateway will attempt to collect payment for the occurrence. (read-only) |
A refund applied to an existing charge.
Parameter | Type | Description |
---|---|---|
id | String | The ID of the entity (read-only) |
source_id | String | The 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) |
created | Timestamp | Date/time the entity was created (read-only) |
modified | Timestamp | Date/time the entity was last modified (read-only) |
messages | Array of Strings | Validation or warning messages associated with an operation requested on this entity (read-only) |
type | String | Type of the transaction, used to differentiate Charges and Refunds in transaction search results. For Refunds, the value is always REFUND. (read-only) |
account_id | String | The ID of the account to provide payment for the Refund (set at creation of the Refund, read-only thereafter) |
status | String | Status of the refund (read-only). Enumeration of:
|
completion_timestamp | datetime | The date and time when the transaction was COMPLETED. If the status is not COMPLETED, this field is null. (read-only) |
failure_code | String | Failure 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. |
amount | Number | The amount to refund, in terms of the currency's smallest unit. For USD, this is the amount in cents. |
currency | String | 3-letter ISO 4217 code representing the currency in which the amount is denominated (optional, defaults to USD) |
charge_id | String | ID of the charge to which the Refund was applied (read-only) |
auto_capture | Boolean | Whether the transaction is automatically captured by the Gateway. For Refunds, this value is always true. (Read-only) |
method | Payment method or ID | Details 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). |
reference | String | An optional comment to be associated with the creation of the Refund. Maximum length is 128 characters. |
data | JSON hash | A JSON hash containing any additional data to be included on the transaction. Storage charges may apply based on the amount of data saved. |
A schedule defining the occurrence of events, such as recurring charge payments.
Parameter | Type | Description |
---|---|---|
interval_unit | String | The interval unit of the schedule. Enumeration of:
|
interval_delay | Number | The 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. |
start | Date | The start date for the schedule such that the first occurrence may be executed on or after this date |
end | Date | The end date for the schedule such that the last occurrence is executed on or before this date (optional) |
days | Array of String | Schedules 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". |
Results of a search performed on a resource type (such as charges).
Parameter | Type | Description |
---|---|---|
page | Number | The logical "page" of the search results represented by this entity |
page_size | Number | The maximum number of results requested per page |
total_entries | Number | The total number of search results available |
results | Array of resource types. The actual type varies with the API used. | The page's search results |
A cardholder's signature.
Parameter | Type | Description |
---|---|---|
mime_type | String | The only supported mime type value is "chargeio/jsignature". (required, maximum length is 64 characters) |
data | jSignature | The signature itself. See https://willowsystems.github.io/jSignature/#/about/ for format information. (required, maximum length is 8192 characters) |
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.
Parameter | Type | Description |
---|---|---|
id | String | The ID of the token, which can be passed in a future Charge or Refund request (read-only) |
created | Timestamp | Date/time the entity was created (read-only) |
modified | Timestamp | Date/time the entity was last modified (read-only) |
messages | Array of Strings | Validation or warning messages associated with an operation requested on this entity (read-only) |
type | String | Type of the payment method (required for eCheck). Enumeration of:
|
number | String | Customer's credit card number (required for card) |
card_type | String | Type of the credit card (optional). Enumeration of:
|
exp_month | Number, 1-12 | Card expiration month (required for card) |
exp_year | Number | 2 or 4-digit card expiration year (required for card) |
cvv | String | Card CVV (required for card) |
routing_number | String | 9-digit routing number of the customer's bank (required for eCheck) |
account_number | String | Customer's bank account number. The value may be 4-17 digits, with no punctuation or other characters. (required for eCheck) |
account_type | String | The type of the customer bank account specified, either checking or savings (required for eCheck). Enumeration of:
|
account_holder_type | String | The type of account holder, either individual or business (required for eCheck) |
name | String | The name of the account holder or business (required for eCheck with business account_holder_type, optional for card) |
given_name | String | The 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) |
surname | String | The 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) |
address1 | String | Customer address (optional) |
address2 | String | Additional address line (optional) |
city | String | Customer city (optional) |
state | String | Customer state. For US and Canada, this must be the 2-letter state or province code. (optional) |
postal_code | String | Customer 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) |
country | String | Customer 2-letter ISO 3166 country code (optional) |
String | Customer email address (optional) | |
phone | String | Customer phone number. No specific format is required, but the total length cannot exceed 22 characters. (Optional) |
reference | String | An external reference for the payment details, such as a customer ID. The length may not exceed 64 characters. (Optional) |
description | String | Description for the payment details, limited to 64 characters (optional) |
form_data | JSON 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. |
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:
The facility attribute specifies the Gateway subsystem from which the error originated. Facilities include:
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"
}
],
...
}
The following message codes are common to the Gateway API and may be returned from most of the operations.
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.
Example
{
"messages": [
{
"code": "not_authorized",
"level": "error",
"message": "Not authorized",
"facility": "gateway"
}
]
}
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.
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.
Example
{
"messages": [
{
"code": "malformed_request",
"level": "error",
"message" : "Unable to process JSON content",
"facility": "gateway"
}
]
}
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").
Example
{
"messages": [
{
"code": "invalid_request",
"level": "error",
"message" : "Invalid request",
"facility": "gateway"
}
]
}
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.
Example
{
"messages": [
{
"code": "no_content",
"level": "error",
"message": "No JSON content received",
"facility": "gateway"
}
]
}
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:
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"
}
]
}
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.
Example
{
"messages": [
{
"code": "invalid_data_encryption",
"level": "error",
"message": "The value could not be decrypted",
"facility": "gateway"
}
]
}
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.
Example
{
"messages": [
{
"context": "Account[wKgFeD0XFtWBPRxEVWcAmg]",
"code": "resource_not_found",
"level": "error",
"message": "Requested resource not found",
"facility": "gateway"
}
]
}
An operation was performed on a REST entity that could not be completed due to the entity's current status.
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 merchant account was specified for a request that requires an account.
Example
{
"messages": [
{
"code": "no_account_specified",
"level": "error",
"message": "An account ID must be specified",
"facility": "gateway"
}
]
}
An operation was attempted as a merchant, but the merchant has been suspended or made inactive.
Example
{
"messages": [
{
"code": "merchant_not_active",
"level": "error",
"message": "Merchant is not active",
"facility": "gateway"
}
]
}
An operation on a merchant was prohibited due to the status of the merchant.
Example
{
"messages": [
{
"code": "unavailable_for_merchant_status",
"level": "error",
"message": "The operation cannot be completed due to the current merchant status",
"facility": "gateway"
}
]
}
An operation was performed on a merchant account for which the status was not ACTIVE.
Example
{
"messages": [
{
"code": "account_not_active",
"level": "error",
"message": "Account is not active",
"facility": "gateway"
}
]
}
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.
Example
{
"messages": [
{
"code": "unavailable_for_merchant_mode",
"level": "error",
"message": "Mode LIVE not supported for account of type TEST",
"facility": "gateway"
}
]
}
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.
Example
{
"messages": [
{
"code": "unavailable_for_merchant_policy",
"level": "error",
"message": "The operation is unavailable due to the current merchant policy",
"facility": "gateway"
}
]
}
The Gateway returns a no_payment_method error code if a payment API is invoked without providing any payment details in the request content.
Example
{
"messages": [
{
"code": "no_payment_method",
"level": "error",
"message": "No payment method was specified",
"facility": "gateway"
}
]
}
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.
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"
}
]
}
A transaction was performed that supplied payment details that were not applicable for the underlying account.
Example
{
"messages": [
{
"code": "incorrect_payment_type",
"level": "error",
"message": "Payment method type not supported by the target account",
"facility": "gateway"
}
]
}
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.
Example
{
"messages": [
{
"code": "payment_method_expired",
"level": "error",
"message": "Payment method expired",
"facility": "gateway"
}
]
}
The Gateway was unable to execute a search request using the parameters provided.
Example
{
"messages": [
{
"code": "search_failed",
"level": "error",
"message": "The search could not be processed as defined",
"facility": "gateway"
}
]
}
The Gateway encountered an unexpected error processing the request.
Example
{
"messages": [
{
"code": "server_error",
"level": "error",
"message": "An unexpected error occurred",
"facility": "gateway"
}
]
}
An attempt was made to update a resource, but another party modified the same resource prior to commit, moving the version ahead.
Example
{
"messages": [
{
"code": "version_conflict",
"level": "error",
"message": "Version conflict",
"facility": "gateway"
}
]
}
The following message codes are returned to indicate validation problems with submitted card details that prevent transactions from being processed.
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.
Example
{
"messages": [
{
"code": "card_number_invalid",
"level": "error",
"facility": "gateway"
}
]
}
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.
Example
{
"messages": [
{
"code": "card_number_incorrect",
"level": "error",
"facility": "gateway"
}
]
}
The Gateway returns a card_expired error if card details are provided corresponding to an expired card.
Example
{
"messages": [
{
"code": "card_expired",
"level": "error",
"facility": "gateway"
}
]
}
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.
Example
{
"messages": [
{
"code": "card_cvv_incorrect",
"level": "error",
"facility": "payment_processor"
}
]
}
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.
Example
{
"messages": [
{
"code": "card_avs_rejected",
"level": "error",
"facility": "payment_processor"
}
]
}
The following message codes are returned to indicate problems processing transactions submitted to the Gateway.
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.
Example
{
"messages": [
{
"code": "no_card_details_or_token_present",
"level": "error",
"facility": "gateway"
}
]
}
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.
Example
{
"messages": [
{
"code": "not_valid_for_transaction_status",
"level": "error",
"facility": "gateway"
}
]
}
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.
Example
{
"messages": [
{
"code": "unavailable_due_to_capture_in_process",
"level": "error",
"facility": "gateway"
}
]
}
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.
Example
{
"messages": [
{
"code": "exceeds_authorized_amount",
"level": "error",
"facility": "gateway"
}
]
}
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.
Example
{
"messages": [
{
"code": "refund_exceeds_transaction",
"level": "error",
"facility": "gateway"
}
]
}
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.
Example
{
"messages": [
{
"code": "currency_mismatch",
"level": "error",
"facility": "gateway"
}
]
}
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.
Example
{
"messages": [
{
"code": "unsupported_currency",
"level": "error",
"facility": "gateway"
}
]
}
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.
Example
{
"messages": [
{
"code": "card_declined",
"level": "error",
"facility": "payment_processor"
}
]
}
The Gateway returns a card_declined_processing_error error if the payment processor indicates a card has been declined due to a processing error.
Example
{
"messages": [
{
"code": "card_declined_processing_error",
"level": "error",
"facility": "payment_processor"
}
]
}
Attempts to create a charge using a card with insufficient funds available results in a card_declined_insufficient_funds being returned by the Gateway.
Example
{
"messages": [
{
"code": "card_declined_insufficient_funds",
"level": "error",
"facility": "payment_processor"
}
]
}
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.
Example
{
"messages": [
{
"code": "card_declined_limit_exceeded",
"level": "error",
"facility": "payment_processor"
}
]
}
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.
Example
{
"messages": [
{
"code": "card_declined_refer_to_issuer",
"level": "error",
"facility": "payment_processor"
}
]
}
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.
Example
{
"messages": [
{
"code": "card_declined_hold",
"level": "error",
"facility": "payment_processor"
}
]
}
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.
Example
{
"messages": [
{
"code": "card_declined_no_account",
"level": "error",
"facility": "payment_processor"
}
]
}
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.
Example
{
"messages": [
{
"code": "card_type_not_accepted",
"level": "error",
"facility": "payment_processor"
}
]
}
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.
Example
{
"messages": [
{
"code": "merchant_trans_max_amount_exceeded",
"level": "error",
"facility": "gateway"
}
]
}
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.
Example
{
"messages": [
{
"code": "merchant_trans_daily_count_exceeded",
"level": "error",
"facility": "gateway"
}
]
}
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.
Example
{
"messages": [
{
"code": "merchant_trans_daily_amount_exceeded",
"level": "error",
"facility": "gateway"
}
]
}
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.
Example
{
"messages": [
{
"code": "merchant_trans_monthly_count_exceeded",
"level": "error",
"facility": "gateway"
}
]
}
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.
Example
{
"messages": [
{
"code": "merchant_trans_monthly_amount_exceeded",
"level": "error",
"facility": "gateway"
}
]
}
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.
Example
{
"messages": [
{
"code": "card_processor_not_available",
"level": "error",
"facility": "payment_processor",
"entity_id": "jCEP6Mn3Q2Cg4nS3qqqDuw"
}
]
}
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.
Example
{
"messages": [
{
"code": "card_processing_error",
"level": "error",
"facility": "payment_processor",
"entity_id": "jCEP6Mn3Q2Cg4nS3qqqDuw"
}
]
}
A transaction that cannot be settled is marked as failed, and its failure code is set to settlement_failed.
Example
{
"messages": [
{
"code": "settlement_failed",
"level": "error",
"facility": "payment_processor"
}
]
}
The following message codes are returned to indicate problems processing eCheck transactions submitted to the Gateway.
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.
Example
{
"messages": [
{
"code": "no_bank_details_or_token_present",
"level": "error",
"facility": "payment_processor"
}
]
}
If the eCheck processor declines the transaction the Gateway returns a ach_declined error and rejects the request.
Example
{
"messages": [
{
"code": "ach_declined",
"level": "error",
"facility": "payment_processor"
}
]
}
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.
Example
{
"messages": [
{
"code": "ach_declined_hold",
"level": "error",
"facility": "payment_processor"
}
]
}
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.
Example
{
"messages": [
{
"code": "ach_declined_duplicate",
"level": "error",
"facility": "payment_processor"
}
]
}
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.
Example
{
"messages": [
{
"code": "ach_invalid_account_number",
"level": "error",
"facility": "payment_processor"
}
]
}
The Gateway returns an ach_invalid_routing_number error code when an invalid routing number is provided for an eCheck transaction.
Example
{
"messages": [
{
"code": "ach_invalid_routing_number",
"level": "error",
"facility": "payment_processor"
}
]
}
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.
Example
{
"messages": [
{
"code": "ach_insufficient_funds",
"level": "error",
"facility": "payment_processor"
}
]
}
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.
Example
{
"messages": [
{
"code": "ach_account_not_found",
"level": "error",
"facility": "payment_processor"
}
]
}
The Gateway returns an ach_account_closed error code when an account involved in an eCheck transaction is reported as closed.
Example
{
"messages": [
{
"code": "ach_account_closed",
"level": "error",
"facility": "payment_processor"
}
]
}
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.
Example
{
"messages": [
{
"code": "ach_account_frozen",
"level": "error",
"facility": "payment_processor"
}
]
}
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.
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.
An eCheck transaction for which payment has been stopped by the account holder is marked as failed with an ach_payment_stopped error code.
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.
The Gateway returns an ach_limit_exceeded error code if the eCheck processor reports a transaction has exceeded the authorized limit.
Example
{
"messages": [
{
"code": "ach_limit_exceeded",
"level": "error",
"facility": "payment_processor"
}
]
}
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.
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.
Example
{
"messages": [
{
"code": "ach_invalid_merchant_configuration",
"level": "error",
"facility": "gateway",
"entity_id": "jCEP6Mn3Q2Cg4nS3qqqDuw"
}
]
}
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.
Example
{
"messages": [
{
"code": "ach_processor_not_available",
"level": "error",
"facility": "gateway",
"entity_id": "jCEP6Mn3Q2Cg4nS3qqqDuw"
}
]
}
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.
Example
{
"messages": [
{
"code": "ach_processing_error",
"level": "error",
"facility": "payment_processor",
"entity_id": "jCEP6Mn3Q2Cg4nS3qqqDuw"
}
]
}
The following message codes are returned to indicate problems processing recurring charge requests submitted to the Gateway.
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.
Example
{
...
"messages": [
{
"code": "no_occurrences_for_schedule",
"level": "error",
"facility": "gateway"
}
]
}
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.
Example
{
...
"messages": [
{
"code": "first_occurrence_due_immediately",
"level": "error",
"facility": "gateway"
}
]
}
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.
Example
{
...
"messages": [
{
"code": "update_results_in_no_occurrences",
"level": "error",
"facility": "gateway"
}
]
}
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.
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.
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:
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.
The Gateway generates the following Events. The data content described for each Event is accessed from the data property of the event.
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": "***"
}
}
}
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": "***"
}
}
}
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
}
}
}
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
}
}
}
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
}
}
}
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"
}
}
}
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,
}
}
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,
}
}
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.
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,
}
}
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.
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,
}
}
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"
}
}
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"
}
}
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"
}
}
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"
}
}
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"
}
}
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"
}
}
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.
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"
}
}
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.
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"
}
}
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
}
}
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
}
}
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"
} ]
}
}
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"
} ]
}
}
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
}
}
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.
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.
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.
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 Code | Description |
---|---|
200 | The operation succeeded |
204 | The operation succeeded, but no response content was returned (normal for APIs that do not return any JSON response). |
400 | The request was malformed. |
401 | Authentication credentials were not provided, or were not valid for the requested operation. |
404 | An item referred to in the request, such as a charge or merchant bank account, was not found. |
409 | There 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. |
422 | The request could not be processed. This is typically due to validation errors reported in the response. |
500 | An error occurred while processing the request. |
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.
GET /contacts
Retrieves a list that includes each Contact that matches the search criteria provided.
Query parameters
Parameter | Type | Description |
---|---|---|
q | String | The text filter to apply across all text fields. (optional) |
qf | String | The 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_by | Array of String | The 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) |
page | Int32 | The page number, starting at 1. The default value is 1. (optional) |
page_size | Int32 | The 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"
}
}
POST /contacts
Creates a Contact using the properties included in the request.
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 /contacts/{contact_id}
Retrieves the specified Contact.
URI parametersParameter | Description |
---|---|
contact_id | The 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 /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 parametersParameter | Description |
---|---|
source_id | The 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"
}
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:
Parameter | Description |
---|---|
contact_id | The 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 /contacts/{contact_id}
Deletes the specified Contact.
URI parametersParameter | Description |
---|---|
contact_id | The 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"
}
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 parametersParameter | Description |
---|---|
contact_id | The 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"
}
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 /contacts/{contact_id}/payment-methods
Retrieves a list that includes each PaymentMethod for the specified Contact.
URI parametersParameter | Description |
---|---|
contact_id | The 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"
}
]
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 parametersParameter | Description |
---|---|
contact_id | The 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 /contacts/{contact_id}/payment-methods/{payment_method_id}
Retrieves the specified PaymentMethod for the specified contact.
URI parametersParameter | Description |
---|---|
contact_id | The system-generated ID of a specific Contact. (ID prefix = p_ or org_) (required) |
payment_method_id | The 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"
}
PATCH /contacts/{contact_id}/payment-methods/{payment_method_id}
Updates the specified PaymentMethod.
URI parametersParameter | Description |
---|---|
contact_id | The system-generated ID of a specific Contact. (ID prefix = p_ or org_) (required) |
payment_method_id | The 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 /contacts/{contact_id}/payment-methods/{payment_method_id}
Deletes the specified PaymentMethod.
URI parametersParameter | Description |
---|---|
contact_id | The system-generated ID of a specific Contact. (ID prefix = p_ or org_) (required) |
payment_method_id | The 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"
}
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.
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 /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 parametersParameter | Description |
---|---|
contact_id | The 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"
}
]
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:
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 parametersParameter | Description |
---|---|
contact_id | The 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"
}
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:
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 parametersParameter | Description |
---|---|
contact_id | The system-generated ID of an organization; in this case, this is the merchant that owns the attachment. (ID prefix = org_) (required) |
attachment_id | The 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 /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 parametersParameter | Description |
---|---|
contact_id | The system-generated ID of an organization; in this case, this is the merchant that owns the attachment. (ID prefix = org_) (required) |
attachment_id | The 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"
}
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.GET /contacts/info-requests
Retrieves a list that contains each InfoRequest.
Query parameters
Parameter | Type | Description |
---|---|---|
order_by | Array of String | The 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) |
page | Int32 | The page number, starting at 1. The default value is 1. (optional) |
page_size | Int32 | The 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 /contacts/{contact_id}/info-requests
Retrieves a list that contains each InfoRequest for the specified contact.
URI parametersParameter | Description |
---|---|
contact_id | The system-generated ID of a specific Contact. (ID prefix = p_ or org_) (required) |
Query parameters
Parameter | Type | Description |
---|---|---|
order_by | Array of String | The 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) |
page | Int32 | The page number, starting at 1. The default value is 1. (optional) |
page_size | Int32 | The 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"
}
]
}
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:
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"
}
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 parametersParameter | Description |
---|---|
inforequest_id | The 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"
}
PATCH /contacts/info-requests/{info_request_id}
Updates the specified InfoRequest to change its status and cancel it.
URI parametersParameter | Description |
---|---|
info_request_id | The 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 /contacts/info-requests/{info_request_id}
Deletes the specified InfoRequest.
URI parametersParameter | Description |
---|---|
info_request_id | The 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
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"
}
]
}
]
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 parametersParameter | Description |
---|---|
contact_id | The 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"
}
]
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.
A contact's address. (ID prefix = addr_)
Parameter | Type | Description |
---|---|---|
type | String | The resource type, which is used to identify objects when they share the same endpoint. (optional, unmodifiable, always in response) |
messages | Array of Message | Issues or general messages that occur during the request are communicated through this object. (optional, ignored in request) |
id | XID | The 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) |
created | AuditTrace | The date and time when the resource was created. This field cannot be updated. (optional, ignored in request, always in response) |
modified | AuditTrace | The date and time when the resource was last modified. (optional, ignored in request, always in response) |
line1 | String | The mailing address of the contact. The length must be 1-64 characters. (required) |
line2 | String | An additional address field. The length must be no more than 64 characters. (optional) |
city | String | The city where the contact is located. The length must be 1-64 characters. (required) |
state_or_province | String | For 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_code | String | The 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_code | String | The 2-letter ISO 3166 country code where the contact is located.</span>. (required) |
preferred | Boolean | Whether postal mail is the preferred method of contact. The default value is false. (optional) |
An entity (representing a person or business organization) that acts within the AffiniPay Payment Portal system.
Union of:
A generated hash for unprivileged access to a Contact.
Parameter | Type | Description |
---|---|---|
messages | Array of Message | Issues or general messages that occur during the request are communicated through this object. (optional, ignored in request) |
hash | String | A unique string that represents temporary, unprivileged access to portal calls. |
url | String | The default portal link from the generated hash. |
contact_id | XID | The system-generated ID of a specific Contact. (ID prefix = p_ or org_, optional) |
A file reference. (ID prefix = fref_)
Parameter | Type | Description |
---|---|---|
id | XID | The 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_name | String | The name of the file. (optional) |
processing_state | String | The current status of the uploaded file. (always in response) One of:
|
reference | String | A description of the file. (optional) |
messages | Array of Message | Issues or general messages that occur during the request are communicated through this object. (optional, ignored in request) |
type | String | The resource type, which is used to identify objects when they share the same endpoint. (optional, unmodifiable, always in response) |
A generated hash for unprivileged access to a Contact and outstanding invoices.
Parameter | Type | Description |
---|---|---|
messages | Array of Message | Issues or general messages that occur during the request are communicated through this object. (optional, ignored in request) |
hash | String | A unique string that represents temporary, unprivileged access to portal calls. |
url | String | The default portal link from the generated hash. |
contact_id | XID | The system-generated ID of a specific Contact. (ID prefix = p_ or org_, optional) |
A contact's email address. (ID prefix = eml_)
Parameter | Type | Description |
---|---|---|
type | String | The resource type, which is used to identify objects when they share the same endpoint. (optional, unmodifiable, always in response) |
messages | Array of Message | Issues or general messages that occur during the request are communicated through this object. (optional, ignored in request) |
id | XID | The 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) |
created | AuditTrace | The date and time when the resource was created. This field cannot be updated. (optional, ignored in request, always in response) |
modified | AuditTrace | The date and time when the resource was last modified. (optional, ignored in request, always in response) |
address | String | The contact's email address. The length must be 1-254 characters. (required) |
preferred | Boolean | Whether an email to this address is the preferred method of contact. The default value is false. (optional) |
A request to save a payment method via the AffiniPay payment portal. (ID prefix = ireq_)
Parameter | Type | Description |
---|---|---|
id | XID | The 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) |
created | AuditTrace | The date and time when the resource was created. This field cannot be updated. (optional, ignored in request, always in response) |
modified | AuditTrace | The date and time when the resource was last modified. (optional, ignored in request, always in response) |
owner_id | XID | The 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_id | XID | The system-generated ID of a specific Contact. (ID prefix = p_ or org_) |
test_mode | Boolean | Whether this resource is used for testing only. The default value is false. (optional, unmodifiable) |
status | String | The current status of the InfoRequest, within its lifecycle.
(optional, ignored in request, always in response) |
message | message | The 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) |
type | String | The resource type, which is used to identify objects when they share the same endpoint. |
An organization. (ID prefix = org_)
Parameter | Type | Description |
---|---|---|
type | String | The resource type, which is used to identify objects when they share the same endpoint. The value must be organization. (required, unmodifiable) |
messages | Array of Message | Issues or general messages that occur during the request are communicated through this object. (optional, ignored in request) |
id | XID | The 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) |
created | AuditTrace | The date and time when the resource was created. This field cannot be updated. (optional, ignored in request, always in response) |
modified | AuditTrace | The date and time when the resource was last modified. (optional, ignored in request, always in response) |
sort_name | String | An 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_name | String | Auto-generated field that can be used for display purposes. It will be the same as name if it is populated; otherwise, it will be:
(optional, ignored in request, always in response) |
preferred_email | String | The 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_id | XID | The 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) |
deleted | Boolean | Whether this contact has been deleted. The default value is false. (optional, ignored in request) |
test_mode | Boolean | Whether this resource is used for testing only. The default value is false. (optional, unmodifiable) |
source_id | String | An 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:
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_zone | String | The 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_code | String | An identifier for the contact that can be used by the merchant. The length must be 1-10 characters. (optional) |
invoice_number_pattern | String | The 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) |
owner | Sparse version of the Organization | The organization that owns the contact. (optional) |
organization_id | XID | The ID of the organization to which this contact belongs. (optional) |
organization | Array of sparse versions of Organization | The organization to which this contact belongs. (optional, ignored in request) |
preferred_currency | String | The ISO 4217 code for the currency used for invoice charges. The length must be no more than 3 characters. (optional) |
addresses | Array of Address | The contact's addresses. A contact is limited to 5 addresses. (optional) |
phone_numbers | Array of PhoneNumber | The contact's phone numbers. A contact is limited to 5 phone numbers. (optional) |
email_addresses | Array of EmailAddress | The contact's email addresses. A contact is limited to 5 email addresses.(optional) |
tags | Array of String | For a Contact to display in AffiniPay's Card Vault, it must have the tag: default |
name | String | The contact's name. (optional) |
members | Array of sparse versions of Contact | The contacts who can act on behalf of this organization. (optional) |
notes | String | Extra details about the object. (optional, maximum length is 1024 characters) |
The payment method that specifies payment details. (ID prefix = pmtd_)
Parameter | Type | Description |
---|---|---|
type | String | The resource type, which is used to identify objects when they share the same endpoint. (optional, unmodifiable, always in response) |
messages | Array of Message | Issues or general messages that occur during the request are communicated through this object. (optional, ignored in request) |
id | XID | The 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) |
created | AuditTrace | The date and time when the resource was created. This field cannot be updated. (optional, ignored in request, always in response) |
modified | AuditTrace | The date and time when the resource was last modified. (optional, ignored in request, always in response) |
payee_id | XID | The 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_type | PaymentType | The type of payment used. (required) One of:
|
account_holder_type | String | The kind of account holder associated with this payment method if the payment_type is bank_account. One of:
|
name | String |
The length must be no more than 256 characters. (optional) |
given_name | String | The 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) |
surname | String | The 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) |
nickname | String | A nickname used to make it easier to identify the payment method. The length must be no more than 256 characters. (optional) |
account_number | String | The account number associated with the payment method. The length must be no more than 32 characters. (optional) |
bank_name | String | The name of bank associated with the payment method. The length must be no more than 256 characters. (optional) |
bank_account_type | String | For 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:
|
card_type | String | For a credit_card payment, the type of credit card.The length must be no more than 64 characters. One of:
|
expiration_month | Integer | For a credit card payment, the expiration month for the credit card. This is required if the payment_type is credit_card. (optional) |
expiration_year | Integer | For a credit card payment, the expiration year for the credit card. This is required if the payment_type is credit_card. (optional) |
preferred | Integer | Whether this is the preferred payment method for the associated contact. The default value is false. (optional) |
one_time_token | String | The 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_token | String | The string ID of a saved payment token, for payment methods that use tokenization. (either one_time_token or saved_payment_token is required) |
test_mode | Boolean | Whether this payment method is a test payment method. The default value is false. (required) |
reference | String | A reference field for partner use to identify the payment method. The length must be no more than 255 characters. (optional) |
allow_future_charges | Boolean | {Deprecated} Whether the merchant is allowed to run future charges on this payment method. The default value is false. (optional) |
authorized_uses | Enumeration | Defines when this payment method is available to a merchant or their client (optional). Enumeration of:
|
A person. (ID prefix = p_)
Parameter | Type | Description |
---|---|---|
type | String | The resource type, which is used to identify objects when they share the same endpoint. The value must be person. (required, unmodifiable) |
messages | array of Message | Issues or general messages that occur during the request are communicated through this object. (optional, ignored in request) |
id | XID | The 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) |
created | AuditTrace | The date and time when the resource was created. This field cannot be updated. (optional, ignored in request, always in response) |
modified | AuditTrace | The date and time when the resource was last modified. (optional, ignored in request, always in response) |
sort_name | String | An 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_name | String | Auto-generated field that can be used for display purposes. It will be the same as name if it is populated; otherwise, it will be:
(optional, ignored in request, always in response) |
preferred_email | String | The 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_id | XID | The 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) |
deleted | Boolean | Whether this contact has been deleted. The default value is false. (optional, ignored in request) |
test_mode | Boolean | Whether this resource is used for testing only. The default value is false. (optional, unmodifiable) |
source_id | String | An 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:
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_zone | String | The 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_code | String | An identifier for the contact that can be used by the merchant. The length must be 1-10 characters. (optional) |
invoice_number_pattern | String | The 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) |
owner | Sparse version of the Organization | The organization that owns the contact. (optional) |
organization_id | XID | The ID of the organization to which this contact belongs. (optional) |
organization | Array of sparse versions of Organization | The organization to which this contact belongs. (optional, ignored in request) |
preferred_currency | String | The ISO 4217 code for the currency used for invoice charges. The length must be no more than 3 characters. (optional) |
addresses | Array of Address | The contact's addresses. A contact is limited to 5 addresses. (optional) |
phone_numbers | Array of PhoneNumber | The contact's phone numbers. A contact is limited to 5 phone numbers.(optional) |
email_addresses | Array of EmailAddress | The contact's email addresses. A contact is limited to 5 email addresses.(optional) |
tags | Array of String | For a Contact to display in AffiniPay's Card Vault, it must have the tag: default |
first_name | String | The first name of the person. The length must be no more than 64 characters. (optional) |
middle_name | String | The middle name of the person. The length must be no more than 64 characters. (optional) |
last_name | String | The last name of the person. The length must be no more than 64 characters. (optional) |
name_prefix | String | The prefix associated with the person's name. The length must be no more than 20 characters. (optional) |
name_suffix | String | The suffix associated with the person's name. The length must be no more than 20 characters. (optional) |
name | String | The person's name. (optional) |
notes | String | Extra details about the object. (optional, maximum length is 1024 characters) |
A contact's phone number. (ID prefix = phn)
Parameter | Type | Description |
---|---|---|
type | String | The resource type, which is used to identify objects when they share the same endpoint. (optional, unmodifiable, always in response) |
messages | array of Message | Issues or general messages that occur during the request are communicated through this object. (optional, ignored in request) |
id | XID | The 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) |
created | AuditTrace | The date and time when the resource was created. This field cannot be updated. (optional, ignored in request, always in response) |
modified | AuditTrace | The date and time when the resource was last modified. (optional, ignored in request, always in response) |
number | String | The contact's phone number. The length must be 5-15 characters. (required) |
extension | String | The contact's phone extension. The length must be no more than 5 characters. (optional) |
preferred | Boolean | Whether a phone call is the preferred method of contact. The default value is false. (optional) |
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.
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.
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 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 Code | Description |
---|---|
200 | The operation succeeded |
204 | The operation succeeded, but no response content was returned (normal for APIs that do not return any JSON response). |
400 | The request was malformed. |
401 | Authentication credentials were not provided, or were not valid for the requested operation. |
404 | An item referred to in the request, such as a charge or merchant bank account, was not found. |
409 | There 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. |
422 | The request could not be processed. This is typically due to validation errors reported in the response. |
500 | An error occurred while processing the request. |
An invoice lists an amount to be paid.
GET /invoices
Retrieves a list that includes each Invoice that matches the search criteria provided.
Query parametersParameter | Type | Description |
---|---|---|
q | String | The text filter to apply across all text fields. (optional) |
qf | String | The 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_by | Array of String | The 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) |
page | Int32 | The page number, starting at 1. The default value is 1. (optional) |
page_size | Int32 | The 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"
}
]
}
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 /invoices/{invoice_id}
Retrieves the specified Invoice.
URI parametersParameter | Description |
---|---|
invoice_id | The 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"
}
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 parametersParameter | Description |
---|---|
invoice_id | The 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 /invoices/{invoice_id}
Deletes the specified Invoice.
URI parametersParameter | Description |
---|---|
invoice_id | The 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"
}
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 ParametersParameter | Description |
---|---|
invoice_id | The 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"}
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 parametersParameter | Description |
---|---|
invoice_id | The system-generated ID of an invoice (ID prefix = i_) (required) |
attachment_id | The 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 /invoices/{invoice_id}/attachments/{attachment_id}
Removes the specified file from the its associated invoice and deletes it from the system.
URI parametersParameter | Description |
---|---|
invoice_id | The system-generated ID of an invoice (ID prefix = inv_) (required) |
attachment_id | The 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"
}
GET /payments
Retrieves a list of each Payment that matches the search criteria provided.
Query parametersParameter | Type | Description |
---|---|---|
start_date | datetime | Limits search results to payments made after the given date. Note: This does not work with q and qf filters. (optional) |
end_date | datetime | Limits search results to payments made before the given date. Note: This does not work with q and qf filters. (optional) |
q | String | The text filter to apply across all text fields. (optional) |
qf | String | The 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_by | Array of String | The 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) |
page | Int32 | The page number, starting at 1. The default value is 1. (optional) |
page_size | Int32 | The 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"
}
]
}
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.
A payment method that specifies payment details. (ID prefix = bank_)
Parameter | Type | Description |
---|---|---|
messages | Array of Message | Issues or general messages that occur during the request are communicated through this object. (optional, ignored in request) |
id | XID | The ID of the resource. (optional) |
name | String | A personalized description of the bank account. (required) |
alias | String | A nickname for the bank account. (optional) |
bank_name | String | The official name of the bank where the account is located. (required) |
trust | Boolean | Whether this bank account is a trust account. (required) |
account_id | String | The masked digits of the end of the bank account. (required) |
test | Boolean | Whether this is a test bank account. The default is false. (optional) |
currency | String | 3-letter ISO currency code identifying the currency used for the account. |
processing_accounts | Array of processing_account | The processing accounts associated with the account. (See merchant_account for details about these parameters.) |
An invoice. (ID prefix = i_)
Parameter | Type | Description |
---|---|---|
messages | Array of Message | Issues or general messages that occur during the request are communicated through this object. (optional, ignored in request) |
type | String | The resource type, which is used to identify objects when they share the same endpoint. (optional, unmodifiable, always in response) |
id | XID | The 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) |
created | AuditTrace | The date and time when the resource was created. This field cannot be updated. (optional, ignored in request, always in response) |
modified | AuditTrace | The date and time when the resource was last modified. (optional, ignored in request, always in response) |
status | String | The current status of the invoice. The length must be 1-64 characters. (optional, always in response) One of:
|
revision_id | String | The current version of the invoice. (optional, always in response) |
invoice_number | String | The number shown on the invoice to identify it.The length must be 1-64 characters. (optional, always in response) |
presentment_status | String | The 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:
|
reference | String | Miscellaneous information about the invoice. The length must be no more than 256 characters. (optional) |
invoice_date | datetime | The 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_date | datetime | The date and time when the invoice is due. (optional) |
total_amount | Integer | The sum of all line items in the invoice. This is a generated value. (optional, ignored in request, always in response, unmodifiable) |
total_amount_due | Integer | The amount that remains to be paid on the invoice, taking into account all previous payments. (optional, ignored in request, always in response, unmodifiable) |
amount_paid | Integer | The amount already paid toward the invoice. (optional, ignored in request, always in response, unmodifiable) |
deleted | Boolean | Whether the invoice was deleted. The default value is false. (optional, ignored in request, unmodifiable) |
test_mode | Boolean | Whether 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) |
currency | String | The 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_id | XID | The 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_id | XID | The 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_id | XID | The 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) |
contact | Sparse version of the Contact | The contact associated with the invoice. (optional, ignored in request, always in response, unmodifiable) |
invoice_payments | Array of InvoicePayment | The payments that have been applied to the invoice. (optional, always in response) |
items | Deprecated | |
line_items | Array of LineItem | The invoice line items, which define charges associated with the invoice. (optional, always in response) |
invoice_messages | Array of InvoiceMessage | The messages sent about the invoice. (optional, always in response) |
attachments | Array of FileReference | Files attached to the invoice. In a request, this is an array of attachment id, each with an fref_ prefix (optional, always in response) |
source_id | String | The 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) |
notes | String | Extra details about the object. (optional, maximum length is 1024 characters) |
An invoice message, which is delivered via email. (ID prefix = imsg_)
Parameter | Type | Description |
---|---|---|
messages | Array of Message | Issues or general messages that occur during the request are communicated through this object. (optional, ignored in request) |
type | String | The resource type, which is used to identify objects when they share the same endpoint. (optional, unmodifiable, always in response) |
id | XID | The 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) |
created | AuditTrace | The date and time when the resource was created. This field cannot be updated. (optional, ignored in request, always in response) |
modified | AuditTrace | The date and time when the resource was last modified. (optional, ignored in request, always in response) |
email_addresses | Array of String | The email addresses where the invoice message was sent. (required) |
subject | String | The 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) |
body | String | The body of the email. (optional, ignored in request, always in response) |
message | String | The invoice message that was included in the email. (optional) |
status | String | The status of the email. (optional, always in response) One of:
|
An invoice payment. (ID prefix = ipmt_)
Parameter | Type | Description |
---|---|---|
messages | Array of Message | Issues or general messages that occur during the request are communicated through this object. (optional, ignored in request) |
type | String | The resource type, which is used to identify objects when they share the same endpoint. (optional, unmodifiable, always in response) |
id | XID | The 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) |
created | AuditTrace | The date and time when the resource was created. This field cannot be updated. (optional, ignored in request, always in response) |
modified | AuditTrace | The date and time when the resource was last modified. (optional, ignored in request, always in response) |
amount | Integer | The amount that was paid toward the invoice. (required) |
direction | String | Whether the invoice is for a charge (inbound) or a credit (outbound). (required) One of:
|
An invoice line item.
Parameter | Type | Description |
---|---|---|
id | String | The UUID of the line item, stored as a base64 string. (optional, ignored in request, always in response) |
code | String | A code that can identify this item to external systems. The length must be no more than 64 characters. (optional) |
description | String | A description of the line item. The length must be 1-256 characters. (required) |
rate_per_quantity | BigDecimalString | The amount charged per unit. (required) |
quantity | BigDecimalString | The number of units to be charged. (required) |
rate_type | String | The units used to measure the rate to be charged for the item. (required) One of:
|
A payment applied to an invoice. (ID prefix = pmt_)
Parameter | Type | Description |
---|---|---|
messages | Array of Message | Issues or general messages that occur during the request are communicated through this object. (optional, ignored in request) |
type | String | The resource type, which is used to identify objects when they share the same endpoint. (optional, unmodifiable, always in response) |
id | XID | The 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) |
created | AuditTrace | The date and time when the resource was created. This field cannot be updated. (optional, ignored in request, always in response) |
modified | AuditTrace | The date and time when the resource was last modified. (optional, ignored in request, always in response) |
direction | String | Whether the payment is for a charge (inbound) or a credit (outbound). (required) One of:
|
amount | Integer | The amount of the payment. The value must be at least 0. (required) |
unallocated_amount | Integer | The amount that hasn't been linked to an invoice payment yet. The value must be at least 0. (required) |
transaction_id | TransactionId | The transaction ID, used to link charges and credits on the Gateway. (optional) |
payment_type | PaymentType | The type of payment used. (required) One of:
|
contact_id | XID | The 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) |
contact | Sparse version of the Contact | The contact who made the payment. (optional, ignored in request, always in response) |
owner_id | XID | The 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_type | String | The type of credit card used. (optional) One of:
|
last4_digits | String | The last four digits of the credit card used. (For credit card payments only.) (optional) |
currency | String | The ISO 4217 code for the currency used for payment. The length must be no more than 3 characters. (required) |
bank_account_id | XID | The 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_name | String | The official name of the bank. (optional) |
bank_account | String | The masked last digits of the merchant's bank account. (optional) |
bank_account_type | String | The type of bank account used. (optional) One of:
|
bank_account_alias | String | A personalized name for the merchant's bank account. (optional) |
status | String | The current status of the payment. (required) One of:
|
failure_message | String | If the payment failed, the reason why it failed. (optional) |
test_mode | Boolean | Whether this payment is a test payment. The default value is false. (required) |
reference | String | Miscellaneous information about the invoice. The length must be no more than 256 characters. (optional) |
invoices | Array of sparse versions of Invoice | The invoices that were paid by this payment. (required) |
failure_email_addresses | Array of String | The email addresses where failure messages are sent. (optional) |
A payment applied to an invoice. (ID prefix = pmt_)
Parameter | Type | Description |
---|---|---|
token_id | String | The 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_id | XID | The 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_type | PaymentType | The 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:
|
direction | String | Whether the payment is for a deposit (inbound) or a withdrawl (outbound) from the bank_account. The default value is inbound. (optional) One of:
|
amount | Integer | The amount of the payment. The value must be at least 1. (required) |
currency | String | The ISO 4217 code for the currency used for payment. The length must be no more than 3 characters. (required) |
reference | String | Miscellaneous information about the invoice. The length must be no more than 256 characters. (optional) |
scheduled_run_time | datetime | The date and time when the payment will be run, if in the future. (optional) |
receipt_email_addresses | Array of String | The email addresses where the payment receipt will be sent. (optional) |
invoice_ids | Array of XID | The IDs of the invoices to be paid. (optional) |