The SysPay Merchant Subscription API allows you to define plans and subscribe users to it. Once subscribed, the subscription lifecycle will be handled by SysPay according to the merchant’s plan definition.
A plan is defined by the following criteria:
A subscription follows a simple lifecycle that goes through the following phases:
This method allows you to define a plan that you will be able to subscribe users to.
URL syntax: | /api/{version}/merchant/plan |
---|---|
Method: | POST |
Name | Type | Details | Mandatory | Description |
---|---|---|---|---|
name | string | w{1,100} | Y | Your name for this plan (e.g your own product reference) |
type | string | SUBSCRIPTION|INSTALMENT | Y | The plan type |
description | string | [ws]{1,300} | N | A description for this plan |
currency | string | [A-Z]{3} | Y | The currency of the trial/initial/billing amounts (ISO-4217) |
trial_amount | int | N | The trial amount in cents. When given, trial_period, trial_period_unit and trial_cycles must be provided. If the given amount is ‘0’, the trial period will be applied but no payment will be taken (SUBSCRIPTION only) | |
trial_period | int | N | The number of trial_period_unit a trial cycle lasts (SUBSCRIPTION only) | |
trial_period_unit | string | enum | N | One of minute, hour, day, week, month, year (SUBSCRIPTION only) |
trial_cycles | int | N | The number of times to repeat the trial phase (typically, 1) (SUBSCRIPTION only) | |
billing_amount | int | Y | The recurring billing amount in cents (SUBSCRIPTION only) | |
billing_period | int | Y | The number of billing_period_unit a billing cycle lasts | |
billing_period_unit | string | enum | Y | One of day, week, month, year |
billing_cycles | int | Y | The number of recurring payments to take. 0 will be until cancellation. For INSTALMENTs, the number of cycles cannot be 0 | |
initial_amount | int | N | The amount of the first payment of the recurring cycles if it is different than the given billing_amount | |
total_amount | int | Y | The total amount in cents to split into multiple payments (INSTALMENT only) | |
retry_map_id | int | N | The custom retry map to use (you need to contact us to setup custom retry maps) | |
default_capture_delay | int | N | The default delay in seconds for a payment to be captured, as part of the plan. This may be overridden at subscription level |
The following request will create a subscription plan with:
{
"name": "Some Product",
"type": "SUBSCRIPTION",
"description": "1 EUR trial, 15 EUR monthly with an extra 35 EUR of setup fees",
"currency": "EUR",
"trial_amount": 100,
"trial_period": 12,
"trial_period_unit": "hour",
"trial_cycles": 1,
"billing_amount": 1500,
"billing_period": 1,
"billing_period_unit": "month",
"initial_amount": 5000,
"default_capture_delay": 100
}
The following request will create an instalment plan for a total of 100 EUR with:
{
"name": "Some Product",
"type": "INSTALMENT",
"description": "100 EUR worth of unicorn ground meat, paid in 3 times (40 EUR then 2*30 EUR)",
"currency": "EUR",
"total_amount": 10000,
"billing_period": 1,
"billing_period_unit": "month",
"billing_cycles": 3,
"initial_amount": 4000,
"default_capture_delay": 100
}
The returned parameters are the same ones given for the request, with the 3 extra properties:
Name | Type | Mandatory | Description |
---|---|---|---|
plan.id | int | Y | The SysPay id for your plan |
plan.created | int | Y | A unix timestamp giving the plan creation date |
plan.status | string | Y | The plan status (ACTIVE / DISABLED / DELETED) |
{
"data": {
"plan": {
"id": 42,
"created": 1386575309,
"status": "ACTIVE",
"name": "Some Product",
"description": "1 EUR trial, 15 EUR monthly with an extra 35 EUR of setup fees",
"currency": "EUR",
"trial_amount": 100,
"trial_period": 12,
"trial_period_unit": "hour",
"trial_cycles": 1,
"billing_amount": 1500,
"billing_period": 1,
"billing_period_unit": "month",
"initial_amount": 5000
}
}
}
This method allows you to update some properties of an existing subscription plan. This will affect all subscriptions linked to this plan. Updating instalment plans is currently not supported.
URL syntax: | /api/{version}/merchant/plan/{id} |
---|---|
Method: | PUT |
Name | Type | Details | Mandatory | Description |
---|---|---|---|---|
trial_amount | int | N | The trial amount in cents. If the given amount is ‘0’, the trial period will be applied but no payment will be taken | |
billing_amount | int | N | The recurring billing amount in cents | |
initial_amount | int | N | The amount of the first payment of the recurring cycles if it is different than the given billing_amount | |
default_capture_delay | int | N | The default delay in seconds for a payment to be captured, as part of the plan. This may be overridden at subscription level |
The following request will update a subscription plan:
{
"trial_amount": 100,
"billing_amount": 1500,
"initial_amount": 5000,
"default_capture_delay": 500
}
The returned parameters are the same ones as the create plan request.
{
"data": {
"plan": {
"id": 42,
"created": 1386575309,
"status": "ACTIVE",
"name": "Some Product",
"description": "1 EUR trial, 15 EUR monthly with an extra 35 EUR of setup fees",
"currency": "EUR",
"trial_amount": 100,
"trial_period": 12,
"trial_period_unit": "hour",
"trial_cycles": 1,
"billing_amount": 1500,
"billing_period": 1,
"billing_period_unit": "month",
"initial_amount": 5000
}
}
}
You can either subscribe a customer to an existing plan (recommended) or create a new plan on-the-fly (which can also be re-used later if needed).
The flow is very similar to the hosted payment page one. A call to this service, if successfull, will give you back a URL to redirect the customer to. He will then be able to choose amongst the available payment methods and return to your site afterwards.
URL syntax: | /api/{version}/merchant/subcription |
---|---|
Method: | POST |
Name | Type | Details | Mandatory | Description |
---|---|---|---|---|
flow | string | HOSTED | Y | The flow to use (hosted or server-2-server) |
subscription.redirect_url | string | N | This URL can overwrite the default Redirect URL | |
subscription.ems_url | string | N | This URL can overwrite the default EMS URL | |
subscription.plan_id | int | N | The plan id to subscribe the user to. If not given, you must provide the plan specifications in the plan property | |
subscription.plan | object | N | The plan specification, mandatory if the plan_id is not given. This object has the same properties as the one used for the plan creation | |
subscription.reference | string | UNIQUE, [ -~]+ (ascii printable characters) | N | Your own reference for this subscription |
subscription.extra | string | max length 300 | N | Extra parameters to be sent back to you on redirect/EMS calls |
subscription.website_id | int | N | The Syspay website reference which the customer makes the payment for (The list of available websites can be checked from the merchant backend) | |
subscription.capture_delay | int | N | The delay in seconds for the payment to be captured, where 0 implies a Rebill and a larger value represents a Pre-Auth Rebill | |
customer.email | string | valid email address | Y | Customer email address |
customer.language | string | [a-z]{2} | N | Customer language (ISO-639-1) (defaults to en) |
{
"flow": "HOSTED",
"subscription": {
"plan_id": 42,
"reference": "52a7026d09420",
"extra": "Q3VyaW9zaXR5IGlzIHRoZSBsdXN0IG9mIHRoZSBtaW5kLiAtIFRob21hcyBIb2JiZXMK",
"redirect_url": "https://mydomain.tld/some/custom/redirect",
"ems_url": "https://mydomain.tld/some/custom/callback",
"capture_delay": 71
},
"customer": {
"email": "test@domain.com",
"language": "en"
}
}
{
"flow": "HOSTED",
"redirect_url": "https://mydomain.tld/some/custom/redirect",
"ems_url": "https://mydomain.tld/some/custom/callback",
"subscription": {
"plan": {
"name": "Some Custom Plan",
"type": "SUBSCRIPTION",
"currency": "EUR",
"trial_amount": 100,
"trial_period": 12,
"trial_period_unit": "hour",
"trial_cycles": 1,
"billing_amount": 1500,
"billing_period": 1,
"billing_period_unit": "month",
"initial_amount": 5000
},
"reference": "52a7026d09420",
"extra": "Q3VyaW9zaXR5IGlzIHRoZSBsdXN0IG9mIHRoZSBtaW5kLiAtIFRob21hcyBIb2JiZXMK"
},
"customer": {
"email": "test@domain.com",
"language": "en"
}
}
Name | Type | Always There | Description |
---|---|---|---|
redirect | string | Y | The URL you should redirect the customer to in order to start the subscription. |
subscription | object | Y | A subscription object, containing the newly created subscription in a PENDING status |
subscription.id | int | Y | The SysPay subscription id |
subscription.plan_id | int | Y | The plan this subscription is linked to. (This could be an unknown id to you if the plan was created on the fly) |
subscription.plan_type | string | Y | The subscription’s plan type (SUBSCRIPTION / INSTALMENT) |
subscription.created | unix timestamp | Y | The subscription’s creation date |
subscription.ems_url | string | N | The URL that is used to notify about events related to this subscription. |
subscription.capture_delay | int | Y | The delay in seconds for the payment to be captured, where 0 implies a Rebill and a larger value represents a Pre-Auth Rebill |
subscription.reference | string | N | Your own reference for this subscription |
subscription.status | string | Y | The subscription status (PENDING) (see Subscription statuses) |
subscription.phase | string | Y | The phase the subscription is in (NEW) (see Subscription phases) |
subscription.customer | object | Y | The customer information |
subscription.customer.id | int | Y | The Syspay reference for this customer |
subscription.customer.firstname | string | N | The customer’s first name |
subscription.customer.lastname | string | N | The customer’s last name |
subscription.customer.email | string | N | The customer’s email address |
subscription.extra | string | N | The extra parameter received upon request |
subscription.start_date | unix timestamp | N | The subscription start date, if it has already been started |
subscription.end_date | unix timestamp | N | The subscription end date, if the subscription is over |
subscription.end_reason | int | N | The end reason for the subscription, if it is over (it could be cancelled by the merchant, stopped because of fraud or expiration of the payment method, etc...) (see Subscription end reasons) |
subscription.next_event | object | N | Information about the next scheduled event for this subscription |
subscription.next_event.event_type | string | Y | The next event type (subscription events) |
subscription.next_event.scheduled_date | unix timestamp | Y | The event’s scheduled date/time |
{
"data": {
"redirect": "https://app.syspay.com/subscription-init-page",
"subscription": {
"id": 4242,
"plan_id": 42,
"plan_type": "SUBSCRIPTION",
"created": 1403105197,
"ems_url": "https://mydomain.tld/some/custom/callback",
"capture_delay": 0,
"reference": "52a7026d09420",
"status": "PENDING",
"phase": "NEW",
"extra": "Q3VyaW9zaXR5IGlzIHRoZSBsdXN0IG9mIHRoZSBtaW5kLiAtIFRob21hcyBIb2JiZXMK",
"customer": {
"email": "test@domain.com",
"language": "fr"
},
"next_event": {
"event_type": "INITIAL",
"scheduled_date": 1403105797
}
}
}
}
Instead of redirecting the customer to our payment page, you could collect the payment method information (e.g. the credit card details) on your own page and forward them directly to us.
The changes to the hosted flow are:
Name | Type | Details | Mandatory | Description |
---|---|---|---|---|
creditcard.cardholder | string | max length 100 | Y | Cardholder name |
creditcard.number | string | [0-9]{12,19} | Y | Valid credit card number, only digits |
creditcard.cvc | int | [0-9]{3,4} | Y | Credit card verification code |
creditcard.exp_month | string | [0-9]{2} | Y | Credit card expire month (ex: 05) |
creditcard.exp_year | string | [0-9]{4} | Y | Credit card expire year (ex: 2015) |
{
"flow": "API",
"method": "CREDITCARD",
"subscription": {
"ems_url": "https://mydomain.tld/some/custom/callback",
"plan_id": 42,
"reference": "52a7026d09420",
"extra": "Q3VyaW9zaXR5IGlzIHRoZSBsdXN0IG9mIHRoZSBtaW5kLiAtIFRob21hcyBIb2JiZXMK"
},
"customer": {
"email": "test@domain.com",
"language": "en",
"ip": "1.2.3.4"
},
"creditcard": {
"cardholder": "John Doe",
"number": "4556253971599407",
"cvc": 123,
"exp_month": "05",
"exp_year": "2015"
}
}
{
"data": {
"subscription": {
"id": 4242,
"plan_id": 42,
"plan_type": "SUBSCRIPTION",
"ems_url": "https://mydomain.tld/some/custom/callback",
"reference": "52a7026d09420",
"status": "ACTIVE",
"phase": "TRIAL",
"extra": "Q3VyaW9zaXR5IGlzIHRoZSBsdXN0IG9mIHRoZSBtaW5kLiAtIFRob21hcyBIb2JiZXMK",
"start_date": 1386631016,
"customer": {
"email": "test@domain.com",
"language": "en"
},
"next_event": {
"event_type": "INITIAL",
"scheduled_date": 1403105797
}
}
}
}
You can subscribe customers that already have an ACTIVE or ENDED subscription or an ACTIVE billing agreement by re-using the payment method linked to them.
The changes to the hosted flow are:
{
"flow": "API",
"subscription": {
"plan_id": 42,
"reference": "52a7026d09420",
"extra": "Q3VyaW9zaXR5IGlzIHRoZSBsdXN0IG9mIHRoZSBtaW5kLiAtIFRob21hcyBIb2JiZXMK",
"redirect_url": "https://mydomain.tld/some/custom/redirect",
"ems_url": "https://mydomain.tld/some/custom/callback"
},
"customer": {
"email": "test@domain.com",
"language": "en"
},
"use_subscription": 845
}
While a subscription is in ACTIVE or ENDED status, you can issue manual rebills or random amount (but same currency) on it. A payment object will be given back.
URL syntax: | /api/{version}/merchant/subscription/{id}/rebill |
---|---|
Method: | POST |
Name | Type | Details | Mandatory | Description |
---|---|---|---|---|
reference | string | UNIQUE, [ -~]+ (ascii printable characters) | N | Merchant payment identifier. If not provided the one used for the subscription will be used |
amount | int | Y | The amount we need to bill in cents (500 XXX = 5.00 XXX) | |
currency | string | [A-Z]{3} | Y | The currency (ISO-4217) |
description | string | max length 300 | N | The product description that the customer is paying for. If not provided the one used for the plan of the subscription will be used |
extra | string | max length 300 | N | Extra parameter that is passed back to the merchant when sending notifications. If not provided the one used for the subscription will be used |
ems_url | string | N | The notification URL for that payment. If not provided the EMS url will be the same one as the subscription’s |
{
"amount": 5000,
"currency": "EUR",
"reference": "83987232",
"description": "extra credits",
"extra": "Q3VyaW9zaXR5IGlzIHRoZSBsdXN0IG9mIHRoZSBtaW5kLiAtIFRob21hcyBIb2JiZXMK"
}
You can cancel any ACTIVE subscription.
URL syntax: | /api/{version}/merchant/subscription/{id}/cancel |
---|---|
Method: | POST |
If this parameter is not needed, an empty body can be sent.
{
"now": true
}
The response will contain the updated subscription data, including an extra end_date and end_reason parameters.
{
"data": {
"subscription": {
"id": 4242,
"plan_id": 42,
"plan_type": "SUBSCRIPTION",
"ems_url": "https://mydomain.tld/some/custom/callback",
"reference": "52a7026d09420",
"status": "ENDED",
"phase": "CLOSED",
"extra": "Q3VyaW9zaXR5IGlzIHRoZSBsdXN0IG9mIHRoZSBtaW5kLiAtIFRob21hcyBIb2JiZXMK",
"start_date": 1386631016,
"end_date": 1386641016,
"end_reason": "UNSUBSCRIBED_MERCHANT",
"customer": {
"email": "test@domain.com",
"language": "fr"
},
"next_event": null
}
}
}