Create a Subscription
Step 1: Create a Customer
If this is a new customer, please use the Create Customer guide to create them in the system. If you already have the customer ID, please jump to Step 2. Let's assume the Customer ID you have is KPxMADVnxMV4nNjp
.
Step 2 - option 1: Tokenize a Card
We will store and tokenize a card credential, then attach it to the customer ID.
POST
https://testapi.payarc.net/v1/tokens
We will use this API to create the token that represents a credit or debit card used to carry out a transaction.
We are assuming the card source is INTERNET
, and will capture the card number 4012000098765439
, expiration month 12
and year 2025
and CVV 999
.
We can choose if we want to perform a zero-dollar authorization, which will ensure that the card is active. Please note that this may result in additional fees. We will set authorize_card to 1
for this example, which will perform the authorization.
import http.client
conn = http.client.HTTPSConnection("testapi.payarc.net")
payload = 'card_source=INTERNET&card_number=4012000098765439&exp_month=12&exp_year=2025&cvv=999&authorize_card=1'
headers = {
'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiI0NTIyIiwianRpIjoiYmQ5NjhjZDVlMDI5ZDg3MGMzNjljZmExOGZkN2IxMTk3MjJlYWQ4YzcxODMzNTM0ZjE0OTU3Zjc1Y2E4ZWI2NmM5MTIwMDk0NTI0NWFmNzMiLCJpYXQiOjE3MDE5MzU4NjEsIm5iZiI6MTcwMTkzNTg2MSwiZXhwIjoxODU5NjE1ODYxLCJzdWIiOiI4NTI2MTg4Iiwic2NvcGVzIjoiKiJ9.KOJALGZ-u8CuRJcapzV22anTy7VGYyEUm3qzAaXVpQfX5rX_8bmuD9Kl2vF4FfvCreJ-cOem0-c3BZLLd6cEOiV4v0kwA2O70g3HCg80g8YCPsw9F3ggOtVFWgLPofBZp56WI0q-slykAQhXQOeM7MbqnHvLUdVQClCTrxb4-_332wyZUbX_zMj2Q_o-Wunzo0DPQhGrBTV7Va-jTXwOfcHcFMtuGTVoCGoz0qqmpO5E5QuAP9DQW2296SWd-zNF90XJ9RiqKN5BUQjx9-0m7TV0ryYpm4H-bhdOwuDpWBrJyIhNsQ9hpOjF8MXEXPho5weJwMKTsDk3iii6x7AAWv_8WvppC0ZGBLxT-TcV09vVumbsm2JVjG8wKLZRYE16Y2VFXrQc8s7TkZ-h-vHbHEGantICV5XdAZ9eTVnSY9NhgNlvsC4DYdw9hL7mW3F5qpT8mqFVzVGDIUMdXkuGuFpX7BZHw-pKU82ID7P3Jxpv8t1QzES7ITyCCGZswtOiNTh8PaPRIcLHtOWxaNUQTk0BCWuvNDesqkRDKBm8bQKfXu3vjBFq-_MHV4HiylGaec_KBSJv0fLyzTcwfHrXFbFFoevJANzw5BMezMwEPWY7XL-tH2LZ3HfiwiQcjFkNYyYVzrzOa-dIzHx0U35BzQdCxKEqxLpgFUY1T-PIr08'
}
conn.request("POST", "/v1/tokens", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
var https = require('follow-redirects').https;
var fs = require('fs');
var qs = require('querystring');
var options = {
'method': 'POST',
'hostname': 'testapi.payarc.net',
'path': '/v1/tokens',
'headers': {
'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiI0NTIyIiwianRpIjoiYmQ5NjhjZDVlMDI5ZDg3MGMzNjljZmExOGZkN2IxMTk3MjJlYWQ4YzcxODMzNTM0ZjE0OTU3Zjc1Y2E4ZWI2NmM5MTIwMDk0NTI0NWFmNzMiLCJpYXQiOjE3MDE5MzU4NjEsIm5iZiI6MTcwMTkzNTg2MSwiZXhwIjoxODU5NjE1ODYxLCJzdWIiOiI4NTI2MTg4Iiwic2NvcGVzIjoiKiJ9.KOJALGZ-u8CuRJcapzV22anTy7VGYyEUm3qzAaXVpQfX5rX_8bmuD9Kl2vF4FfvCreJ-cOem0-c3BZLLd6cEOiV4v0kwA2O70g3HCg80g8YCPsw9F3ggOtVFWgLPofBZp56WI0q-slykAQhXQOeM7MbqnHvLUdVQClCTrxb4-_332wyZUbX_zMj2Q_o-Wunzo0DPQhGrBTV7Va-jTXwOfcHcFMtuGTVoCGoz0qqmpO5E5QuAP9DQW2296SWd-zNF90XJ9RiqKN5BUQjx9-0m7TV0ryYpm4H-bhdOwuDpWBrJyIhNsQ9hpOjF8MXEXPho5weJwMKTsDk3iii6x7AAWv_8WvppC0ZGBLxT-TcV09vVumbsm2JVjG8wKLZRYE16Y2VFXrQc8s7TkZ-h-vHbHEGantICV5XdAZ9eTVnSY9NhgNlvsC4DYdw9hL7mW3F5qpT8mqFVzVGDIUMdXkuGuFpX7BZHw-pKU82ID7P3Jxpv8t1QzES7ITyCCGZswtOiNTh8PaPRIcLHtOWxaNUQTk0BCWuvNDesqkRDKBm8bQKfXu3vjBFq-_MHV4HiylGaec_KBSJv0fLyzTcwfHrXFbFFoevJANzw5BMezMwEPWY7XL-tH2LZ3HfiwiQcjFkNYyYVzrzOa-dIzHx0U35BzQdCxKEqxLpgFUY1T-PIr08'
},
'maxRedirects': 20
};
var req = https.request(options, function (res) {
var chunks = [];
res.on("data", function (chunk) {
chunks.push(chunk);
});
res.on("end", function (chunk) {
var body = Buffer.concat(chunks);
console.log(body.toString());
});
res.on("error", function (error) {
console.error(error);
});
});
var postData = qs.stringify({
'card_source': 'INTERNET',
'card_number': '4012000098765439',
'exp_month': '12',
'exp_year': '2025',
'cvv': '999'
'authorize_card': '1'
});
req.write(postData);
req.end();
var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "https://testapi.payarc.net/v1/tokens");
request.Headers.Add("Accept", "application/json");
request.Headers.Add("Authorization", "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiI0NTIyIiwianRpIjoiYmQ5NjhjZDVlMDI5ZDg3MGMzNjljZmExOGZkN2IxMTk3MjJlYWQ4YzcxODMzNTM0ZjE0OTU3Zjc1Y2E4ZWI2NmM5MTIwMDk0NTI0NWFmNzMiLCJpYXQiOjE3MDE5MzU4NjEsIm5iZiI6MTcwMTkzNTg2MSwiZXhwIjoxODU5NjE1ODYxLCJzdWIiOiI4NTI2MTg4Iiwic2NvcGVzIjoiKiJ9.KOJALGZ-u8CuRJcapzV22anTy7VGYyEUm3qzAaXVpQfX5rX_8bmuD9Kl2vF4FfvCreJ-cOem0-c3BZLLd6cEOiV4v0kwA2O70g3HCg80g8YCPsw9F3ggOtVFWgLPofBZp56WI0q-slykAQhXQOeM7MbqnHvLUdVQClCTrxb4-_332wyZUbX_zMj2Q_o-Wunzo0DPQhGrBTV7Va-jTXwOfcHcFMtuGTVoCGoz0qqmpO5E5QuAP9DQW2296SWd-zNF90XJ9RiqKN5BUQjx9-0m7TV0ryYpm4H-bhdOwuDpWBrJyIhNsQ9hpOjF8MXEXPho5weJwMKTsDk3iii6x7AAWv_8WvppC0ZGBLxT-TcV09vVumbsm2JVjG8wKLZRYE16Y2VFXrQc8s7TkZ-h-vHbHEGantICV5XdAZ9eTVnSY9NhgNlvsC4DYdw9hL7mW3F5qpT8mqFVzVGDIUMdXkuGuFpX7BZHw-pKU82ID7P3Jxpv8t1QzES7ITyCCGZswtOiNTh8PaPRIcLHtOWxaNUQTk0BCWuvNDesqkRDKBm8bQKfXu3vjBFq-_MHV4HiylGaec_KBSJv0fLyzTcwfHrXFbFFoevJANzw5BMezMwEPWY7XL-tH2LZ3HfiwiQcjFkNYyYVzrzOa-dIzHx0U35BzQdCxKEqxLpgFUY1T-PIr08");
var collection = new List<KeyValuePair<string, string>>();
collection.Add(new("card_source", "INTERNET"));
collection.Add(new("card_number", "4012000098765439"));
collection.Add(new("exp_month", "12"));
collection.Add(new("exp_year", "2025"));
collection.Add(new("cvv", "999"));
collection.Add(new("authorize_card", "1"));
var content = new FormUrlEncodedContent(collection);
request.Content = content;
var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
Console.WriteLine(await response.Content.ReadAsStringAsync());
We will receive a Token object - in this case it has the ID NmLY0wmqEYq8w8ql
{
"data": {
"object": "Token",
"id": "NmLY0wmqEYq8w8ql",
"used": false,
"ip": null,
"tokenization_method": null,
"created_at": 1620129151,
"updated_at": 1620129151,
"card": {
"data": {
"object": "Card",
"id": "15y2901N9L2L0MLv",
"address1": null,
"address2": null,
"card_source": "INTERNET",
"card_holder_name": null,
"is_default": 0,
"exp_month": "12",
"exp_year": "2025",
"is_verified": 0,
"fingerprint": "my905PmvmPNmNP0M",
"city": null,
"state": null,
"zip": null,
"brand": "V",
"last4digit": "5439",
"first6digit": 401200,
"country": null,
"avs_status": null,
"cvc_status": null,
"address_check_passed": 0,
"zip_check_passed": 0,
"customer_id": null,
"created_at": 1620129151,
"updated_at": 1620129151
}
}
},
"meta": {
"include": [],
"custom": []
}
}
We will then link the token ID we received to the customer. It will become the default payment credential.
PATCH
https://api.payarc.net/v1/customers/{customer_id}
Remember, our customer ID was KPxMADVnxMV4nNjp
, so we will have to PATCH
https://api.payarc.net/v1/customers/KPxMADVnxMV4nNjp
The only parameter we need to send is our Token ID, NmLY0wmqEYq8w8ql
var request = require('request');
var options = {
'method': 'PATCH',
'url': 'https://api.payarc.net/v1/customers/{{customer_id}}',
'headers': {
'Authorization': '{{bearer_token}}',
'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded'
},
form: {
'token_id': 'NmLY0wmqEYq8w8ql'
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
Step 2 - option 2: Add a bank account
POST
https://api.payarc.net/v1/bankaccounts/{id}
We will store the bank account information for the customer performing the transaction.
Parameter | Description |
---|---|
account_number Required | Account Number for the account. Format: Numeric, Length 3-17. Example: 0114584906 |
routing_number Required | Nine-digit routing number for the account. Format: Numeric, Length:9 Example: 129131673 |
first_name Required | Account holder's first name Format: AlphaNumeric, Length 2-50 Example: John |
last_name Required | Account holder's first name Format: AlphaNumeric, Length 2-50 Example: Hancock |
account_type Required | The type of account Format: One of the following: Personal Checking , Personal Savings , Business Checking , Business Savings Example: Personal Checking |
customer_id Optional | The Customer ID against which a new subscription will be created Format: AlphaNumeric Example: KPxMADVnxMV4nNjp |
import http.client
conn = http.client.HTTPSConnection("api.payarc.net")
payload = 'account_number=%0114584906%22&routing_number=%129131673%22&first_name=%22John%22&last_name=%22Hancock%22&account_type=%22Personal%20Checking%22&&customer_id=%22KPxMADVnxMV4nNjp%22'
headers = {
'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Bearer {{Access-Token-From-Payarc-Dashboard}}'
}
conn.request("POST", "/v1/bankaccounts", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
var request = require('request');
var options = {
'method': 'POST',
'url': 'https://api.payarc.net/v1/bankaccounts',
'headers': {
'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Bearer {{Access-Token-From-Payarc-Dashboard}}'
},
form: {
'account_number': '"0114584906"',
'routing_number': '"129131673"',
'first_name': '"John"',
'last_name': '"Hancock"',
'account_type': '"Personal Checking"',
'customer_id': '"DjPnVDNApDDnVpMN"'
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "https://api.payarc.net/v1/bankaccounts");
request.Headers.Add("Accept", "application/json");
request.Headers.Add("Authorization", "Bearer {{Access-Token-From-Payarc-Dashboard}}");
var collection = new List<KeyValuePair<string, string>>();
collection.Add(new("account_number", "\"0114584906\""));
collection.Add(new("routing_number", "\"129131673\""));
collection.Add(new("first_name", "\"John\""));
collection.Add(new("last_name", "\"Hancock\""));
collection.Add(new("account_type", "\"Personal Checking\""));
collection.Add(new("customer_id", "\"DjPnVDNApDDnVpMN\""));
var content = new FormUrlEncodedContent(collection);
request.Content = content;
var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
Console.WriteLine(await response.Content.ReadAsStringAsync());
You will receive a BankAccount
object.
Step 3: Create a Plan
In order to create a subscription, you need to have configured a plan that the subscription will be linked to. The plan is the template you will use for all customers, and a subscription is a specific user's instance of a plan.
If you have already configured plans, please find the relevant plan ID, we will assume it is Yq8wLY0wmqE8qlNm
and skip to the next step. Otherwise, let's configure your first plan.
POST
https://api.payarc.net/v1/plans
Let's say that you want to create a subscription for a magazine, for $10 a month.
You can use an internal ID for the plan, let's call it plan_id=Magazine10Monthly
. Otherwise, Payarc will generate a plan ID for you.
The amount to be charged is represented in cents, so we will have to use 1000
to represent our $10 subscription.
We will also name the plan Magazine subscription for $10
and set the interval
for billing to month
and interval_count
to 1
, to represent that we will be billing every month. If we had wanted to bill every second month, we would have set interval_count
to 2
.
We will also have to provide a short description for the plan in the statement_descriptor, it should be between 5 and 25 characters. We will choose "Magazine subscription 10 2024"
We will signal that this is a digital plan by setting plan_type as digital
.
import http.client
conn = http.client.HTTPSConnection("https")
payload = 'amount=1000¤cy=usd&interval=month&interval_count=1&name=Magazine%20subscription%20for%20%2410&plan_code=Magazine10Monthly&statement_descriptor=Magazine%20subscription%2010%202024'
headers = {
'Authorization': '{{bearer_token}}',
'Accept': 'application/json'
}
conn.request("POST", "//api.payarc.net/v1/plans", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
var request = require('request');
var options = {
'method': 'POST',
'url': 'https://api.payarc.net/v1/plans',
'headers': {
'Authorization': '{{bearer_token}}',
'Accept': 'application/json'
},
form: {
'amount': ' 1000',
'currency': 'usd',
'interval': 'month',
'interval_count': ' 1',
'name': 'Magazine Subscription for $10',
'plan_code': 'Magazine10Monthly',
'statement_descriptor': 'Magazine subscription 10 2024',
'trial_period_days': '3'
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "https://api.payarc.net/v1/plans");
request.Headers.Add("Authorization", "{{bearer_token}}");
request.Headers.Add("Accept", "application/json");
var collection = new List<KeyValuePair<string, string>>();
collection.Add(new("amount", " 1000"));
collection.Add(new("currency", "usd"));
collection.Add(new("interval", "day"));
collection.Add(new("interval_count", " 1"));
collection.Add(new("name", "Magazine subscription for $10"));
collection.Add(new("plan_code", "Magazine10Monthly"));
collection.Add(new("statement_descriptor", "Magazine subscription 10 2024"));
var content = new FormUrlEncodedContent(collection);
request.Content = content;
var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
Console.WriteLine(await response.Content.ReadAsStringAsync());
We will receive a Plan object.
{
"data": {
"object": "Plan",
"id": "Yq8wLY0wmqE8qlNm",
"real_id": 9,
"amount": "1000",
"interval": "month",
"interval_count": "1",
"name": "Magazine subscription for $10",
"description": null,
"statement_descriptor": "Magazine subscription 10 2024",
"currency": "usd",
"created_at": {
"date": "2018-11-27 09:15:59.000000",
"timezone_type": 3,
"timezone": "UTC"
},
"updated_at": {
"date": "2018-11-27 09:15:59.000000",
"timezone_type": 3,
"timezone": "UTC"
}
},
"meta": {
"include": [],
"custom": []
}
}
Step 4 (optional): Create a Coupon
If you wish to offer either a percent off subscriptions, or an amount off, you can create a coupon, and at the next step, apply it to a subscription. The same coupon can be applied to multiple subscriptions.
If you have already created a coupon, grab its ID and skip to the next step.
POST
https://api.payarc.net/v1/discounts
Let's suppose we want to create a discount code named 3MONTHS10
that will offer 10% off for the first 3 months of a subscription. We will set the name
to 3MONTHS10
, duration
set to repeating
, duration_in_months
to 3
and percent_off
to 10
.
If you want to offer high-value discounts, or discounts personalized to certain groups of users, you should use a discount code name that is hard to guess or randomly generated, instead.
import http.client
conn = http.client.HTTPSConnection("api.payarc.net")
payload = 'name=3MONTHS10&duration=repeating&duration_in_months=3&percent_off=10'
headers = {
'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Bearer {{Access-Token-From-Payarc-Dashboard}}'
}
conn.request("POST", "/v1/discounts", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "https://api.payarc.net/v1/discounts");
request.Headers.Add("Accept", "application/json");
request.Headers.Add("Authorization", "Bearer {{Access-Token-From-Payarc-Dashboard}}");
var collection = new List<KeyValuePair<string, string>>();
collection.Add(new("name", "3MONTHS10"));
collection.Add(new("duration", "repeating"));
collection.Add(new("duration_in_months", "3"));
collection.Add(new("percent_off", "10"));
var content = new FormUrlEncodedContent(collection);
request.Content = content;
var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
Console.WriteLine(await response.Content.ReadAsStringAsync());
var https = require('follow-redirects').https;
var fs = require('fs');
var qs = require('querystring');
var options = {
'method': 'POST',
'hostname': 'api.payarc.net',
'path': '/v1/discounts',
'headers': {
'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Bearer {{Access-Token-From-Payarc-Dashboard}}'
},
'maxRedirects': 20
};
var req = https.request(options, function (res) {
var chunks = [];
res.on("data", function (chunk) {
chunks.push(chunk);
});
res.on("end", function (chunk) {
var body = Buffer.concat(chunks);
console.log(body.toString());
});
res.on("error", function (error) {
console.error(error);
});
});
var postData = qs.stringify({
'name': '3MONTHS10',
'duration': 'repeating',
'duration_in_months': '3',
'percent_off': '99'
});
req.write(postData);
req.end();
We will receive the new coupon ID dc_c7cc1e9c
Step 5: Create a Subscription
Now we will put everything together and create a subscription for our customer idKPxMADVnxMV4nNjp
, using our plan Yq8wLY0wmqE8qlNm
, applying our coupon dc_c7cc1e9c
.
We will not set up a subscription end date.
In order to charge the customer's card on file automatically, we will set the billing_type
to 1
.
We will POST
to the endpoint https://api.payarc.net/v1/subscriptions
import http.client
conn = http.client.HTTPSConnection("api.payarc.net")
payload = 'customer_id=KPxMADVnxMV4nNjp&plan_id=Yq8wLY0wmqE8qlNm&discount_id=dc_c7cc1e9c&billing_type=1'
headers = {
'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Bearer {{Access-Token-From-Payarc-Dashboard}}'
}
conn.request("POST", "/v1/subscriptions", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
var https = require('follow-redirects').https;
var fs = require('fs');
var qs = require('querystring');
var options = {
'method': 'POST',
'hostname': 'api.payarc.net',
'path': '/v1/subscriptions',
'headers': {
'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Bearer {{Access-Token-From-Payarc-Dashboard}}'
},
'maxRedirects': 20
};
var req = https.request(options, function (res) {
var chunks = [];
res.on("data", function (chunk) {
chunks.push(chunk);
});
res.on("end", function (chunk) {
var body = Buffer.concat(chunks);
console.log(body.toString());
});
res.on("error", function (error) {
console.error(error);
});
});
var postData = qs.stringify({
'customer_id': 'KPxMADVnxMV4nNjp',
'plan_id': 'Yq8wLY0wmqE8qlNm',
'discount_id': 'dc_c7cc1e9c',
'billing_type': '1'
});
req.write(postData);
req.end();
var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "https://api.payarc.net/v1/subscriptions");
request.Headers.Add("Accept", "application/json");
request.Headers.Add("Authorization", "Bearer {{Access-Token-From-Payarc-Dashboard}}");
var collection = new List<KeyValuePair<string, string>>();
collection.Add(new("customer_id", "KPxMADVnxMV4nNjp"));
collection.Add(new("plan_id", "Yq8wLY0wmqE8qlNm"));
collection.Add(new("discount_id", "dc_c7cc1e9c"));
collection.Add(new("billing_type", "1"));
var content = new FormUrlEncodedContent(collection);
request.Content = content;
var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
Console.WriteLine(await response.Content.ReadAsStringAsync());
We will receive the new subscription ID dc_c7cc1e9c
Updated 5 months ago