Subscriptions
Geidea offers a Subscription API that helps you manage recurring payments as part of your business applications or platforms. This API enables you to offer customers recurring payment features, a model often utilized by businesses that require collecting payments at regular intervals like streaming platforms, Software as a Service (SaaS) products, automated billing processes ,and more.
You can choose from the below two modes of subscription based on your business needs:
- Recurring Payments: It is a payment model where the customers authorize you to charge their card automatically at regular intervals for the goods/services provided to them.
For Recurring payments, make sure your customer agrees to automatic deductions at set intervals until cancellation or subscription expiry.
- Recurring Payment Links/Scheduled Invoices: You can use this payment model when you want to only schedule sending Payment Links to your customers in exchange of your services.
Advantages:
- Recurring Payments and Recurring Pay links are convenient for both customers and businesses.
- Automated recurring payments cut down the effort associated with manual invoicing and payment processing.
If you are already using our Create Session API Create Session API, you can easily set up subscriptions by passing the subscription ID generated from the Subscription API to the session creation. This process will let customers choose a subscription plan on your website and then show the payment page. It allows you to collect payments directly from your website without needing to share a Payment Link with the customer.
When setting up a subscription for a customer, you must pass customer details in case the subscription is for a new customer, or if the customer already exists, just pass the customer ID.
Subscription API Request
To initiate a Subscription API call, you will need to provide the following fields.
Parameter | Datatype | Description | Mandatory |
---|---|---|---|
recurringPaymentAmount | Float | Subscription amount ex: 100.00 | Yes |
currency | String | Currency of subscription ex: AED | Yes |
cycleInterval | String | Frequency for which a subscription transaction must be executed Valid values: day, week, month, year | Yes |
cycleFrequency | Integer | Number of times the subscription must be executed 1, 2, etc... | Yes |
typeOfPayment | String | Indicates type of Recurring Payment. Valid values: "RecurringPayment", "RecurringLink" RecurringPayment: means subsequent payment will be auto-collected from the customer based on his first payment RecurringLink: means a payment link will be sent to the customer based on the cycle interval and frequency. The customer needs to be present every time to pay If you are using Geidea Session or direct API's then you can pass typeOfPayment" = 'RecurringPayment"& "isFirstPmtPBL":false and collect the first payment from the customer via HPP. The subsequent payments will be auto-collected from the customer based on the scheduled job | Yes |
customerRequest | Object | Details of the customer required to create a customer. Once a customer is created you can send the customer Id in all future subscription requests. One of customerRequest Object or customerId is mandatory. | Conditional |
customerRequest.name | String | Customer Name | Conditional |
customerRequest.email | String | Email of customer. One of email or phoneNumber must be present. | Conditional |
customerRequest.phoneCountryCode | String | Country code of customer's phone number eg: "+971". If phoneNumber is passed, phoneCountryCode must be passed. | Conditional |
customerRequest.phone | String | Customer's phone number eg: "511111111". If phoneCountryCode is passed, phoneNumber must be passed. One of email or phoneNumber must be present. | Conditional |
customerRequest.number | String | Conditional | |
customerId | String | If you have already created a customer using the customerRequest object, you can pass it here. One of customerRequest Object or customerId is mandatory. | Conditional |
description | string | The description of the subscription ex: TV channel plan A | No |
startDate | datetime | Start date of subscription. Ex: "2024-03-05T09:26:07.472Z" | No |
endDate | datetime | The end date of the subscription. For creating an endless subscription do not pass the endDate. For creating a subscription for a specific period, pass the endDate or numberOfPayments | Conditional |
numberOfPayments | string | The number of payments for the subscription. For creating an endless subscription do not pass the endDate. For creating a subscription for a specific period, pass the endDate or numberOfPayments | Conditional |
language | string | The language to be used on the checkout page. Default value: "en" | No |
isFirstPmtPBL | boolean | Use this parameter as with value true or false depending upon how you would like to collect the first payment. If you pass this as true the customer will receive the first payment request as a payment link. If you are using Geidea Session or direct API's please pass the value as false. Default value will be true | No |
paylinkExpirationPeriod | string | The payment link expiration date, is required only when the isFirstPmtPBL parameter is set to true. The default expiration period for the payment link is 7 days. If you want to use any cycle frequency less than 7 days, please make sure you are passing the expiration period accordingly. | No |
timestamp | string | The timestamp of the moment at which the create subscription request has been initiated. | No |
signature | string | A parameter to ensure the security and authenticity of API communications. It involves generating a signature using the contents of the API request and secret keys, which is then sent along with the request. | Yes |
AmountVariability | string | Indicates whether the subscription amount is fixed or changing during the subscription. If value is "FIXED" then the amount/cycle related parameters cannot be changed during the subscription. If the value is "VARIABLE" then amount/cycle related parameters can be changed for the subscription. | No |
Usage of the API environment endpoints
Please make sure you use the correct endpoint based on your environment
- KSA Environment: https://api.ksamerchant.geidea.net/
- Egypt Environment: https://api.merchant.geidea.net/
- UAE Environment: https://api.geidea.ae/
The Amount Variability parameter must remain constant throughout a subscription.
If a subscription is set with a FIXED amount variability, it should remain unchanged until cancellation or completion. Any alteration to the amount variability should be considered a new agreement, requiring the creation of a new subscription.
Signature creation for Create Subscription request
We have a signature parameter in the Create Subscription API to have an additional layer of security during payment processing. To generate the signature, follow the steps below:
- Concatenate the string of {MerchantPublicKey, amount, currency, TimeStamp}
- Hash (SHA-256) this Concatenated string by (Merchant_API_Password)
- Convert Hashed Value to Base64Str
Sample Request for Subscription Creation with CustomerRequest :
curl --location 'https://api.merchant.geidea.net/subscriptions/api/v1/direct/subscription' \
--header 'accept: text/plain' \
--header 'Authorization: Basic ZGI1ZDk1N2QtYTBmZC00YTFlLTkzMTItNWViN2FlNmIzZGI0OjA0NWRjYTJhLWM4MzMtNDVmMC04ZjIyLTQ0NGU1MGIwOGYwYw==' \
--header 'Content-Type: application/json' \
--data-raw '{
"recurringPaymentAmount": "100",
"currency": "AED",
"cycleInterval": "month",
"cycleFrequency": 3,
"typeOfPayment": "RecurringPayment",
"customerRequest": {
"name": "hsbc",
"email": "[email protected]",
"phoneCountryCode": "+971",
"phone": "529872786",
"number": "467715071205"
},
"description": "Subscription #453293393959",
"startDate": "2024-03-17T09:26:07.472Z",
"endDate": null,
"numberOfPayments": 3,
"language": "EN",
"paylinkExpirationPeriod": "1",
"isFirstPmtPBL":false,
"AmountVariability" : "VARIABLE",
"timestamp": null,
"signature": "tF04+uS/SE+z4Bx6JxtO7UAd/srkX9KK7pM3Ertp2iM="
}'
Sample Request for Subscription Creation using CustomerId :
curl --location 'https://api.merchant.geidea.net/subscriptions/api/v1/direct/subscription' \
--header 'accept: text/plain' \
--header 'Authorization: Basic ZGI1ZDk1N2QtYTBmZC00YTFlLTkzMTItNWViN2FlNmIzZGI0OjA0NWRjYTJhLWM4MzMtNDVmMC04ZjIyLTQ0NGU1MGIwOGYwYw==' \
--header 'Content-Type: application/json' \
--data '{
"recurringPaymentAmount": "100",
"currency": "AED",
"cycleInterval": "month",
"cycleFrequency": 3,
"typeOfPayment": "RecurringPayment",
"customerId": "aa6d9ce5-7441-4fff-7328-08dc3cbb2fe8",
"description": "Subscription #453293393959",
"startDate": "2024-03-17T09:26:07.472Z",
"endDate": null,
"numberOfPayments": 3,
"language": "EN",
"paylinkExpirationPeriod": "1",
"isFirstPmtPBL":false,
"AmountVariability" : "VARIABLE",
"timestamp": null,
"signature": "tF04+uS/SE+z4Bx6JxtO7UAd/srkX9KK7pM3Ertp2iM="
}'
You can find a full list of parameters which can be used with the Subscription API here.
API Response
The key parameters sent in the API response are as follows:
Parameter | Description |
---|---|
subscriptionId | Reference for subscription transaction. This parameter must be used when creating a session before initiating a subscription payment transaction. |
occurences | This object will display all the occurrences along with its unique id and status. The number of occurrences in this object will be dependent on the number of payments you are collecting from your customer. |
occurrences.occurrenceId | Unique occurrence id associated with a payment. |
occurrences.type | The type of the payment which will always be "Recurring" in case of Subscriptions |
occurrences.retries | Incase of failed auto debit against your customer's card. We will retry the payment twice after the failure. The retry id and details associated with it will be updated here. |
occurrences.status | The status of the occurrence whether the payment has been processed or "not processed" |
occurrences.paylinkId | If the subscription was created with Recurring Payment link as type of payment then each occurrence will be linked to a Paylink id |
occurrences.orderId | OrderID associated with the payment for the subscription |
occurrences.isInFinalStatus | Final status of the occurrence. For Eg : if the payment in not processed and is awaiting payment tis field would have final status as False. Once paid successfully the final status of the occurrence will be True |
nextOccurrenceDate | Next payment due date of the subscription |
status | Status of subscription creation |
paylinkExpirationPeriod | Expiry date for payment link if the mode of subscription is chosen as payment link |
numberOfPayments | Total number of payments for a subscription |
customerId | Customer ID for whom the subscription is created If the customer does not exist, the customer is created and the customer ID is returned in the response. |
agreementId | Incase of payment type "recurring payment" the first payment method is saved against a tokenid and an agreement id is autogenerated which can be mapped against the agreement with your customer in your system. |
signature | A parameter to ensure the security and authenticity of API communications. It involves generating a signature using the contents of the API response and secret keys, which is then sent along with the response |
amountVariability | Indicates whether the subscription amount is fixed or changing during the subscription. If value is "FIXED" then the amount does not change during the subscription. If the value is "VARIABLE" then amount can be changed for the subscription. Note: If "FIXED" is used then "currency", "recurringPaymentAmount" and "cycleFrequency" can't be updated |
applePayRecurringToken | A token used to debit customers through the use of an Apple Pay encrypted payment |
Signature creation for Cancel Subscription response
We have signature parameter in the Subscription API response to provide an additional layer of security when sending to the merchant the response of the "Create Subscription" API. To generate the signature to confirm if it matches the signature passed in the response, follow the steps below:
- Concatenate the parameters (MerchantPublicKey, recurringPaymentAmount, subscriptionId, status)
- Hash the concatenated string with the MerchantPrivateKey (API password) as a key (algorithm for hashing: SHA256)
- Convert Hashed Value to Base64Str
Sample Response
{
"subscription": {
"customerName": "hsbc",
"customerEmail": "[email protected]",
"customerPhoneCountryCode": "+971",
"customerPhone": "529872786",
"customerAddresses": [],
"subscriptionId": "8a055aa4-13d9-4f74-421d-08dc3cbb381c",
"merchantId": "0ee5274f-5b1a-4415-62a8-08dc20998061",
"merchantPublicKey": "db5d957d-a0fd-4a1e-9312-5eb7ae6b3db4",
"description": "Subscription #453293393959",
"recurringPaymentAmount": 100,
"currency": "AED",
"initialPaymentAmount": null,
"initialPaymentExpirationPeriod": null,
"startDate": "2024-03-08T00:00:00Z",
"endDate": "2124-03-08T00:00:00Z",
"cycleInterval": "Month",
"cycleFrequency": 3,
"timestamp": null,
"signature": "tF04+uS/SE+z4Bx6JxtO7UAd/srkX9KK7pM3Ertp2iM=",
"occurrences": [
{
"occurrenceId": "9c6e2c11-82c1-4fc2-7e67-08dc3cbb3826",
"subscriptionId": "8a055aa4-13d9-4f74-421d-08dc3cbb381c",
"type": "Recurring",
"amount": 100,
"date": "2024-03-08T00:00:00Z",
"status": "NotProcessed",
"retries": [],
"paylinkId": null,
"orderId": null,
"isInFinalStatus": false
}
],
"nextOccurrenceDate": "2024-03-08T00:00:00Z",
"status": "Created",
"typeOfPayment": "RecurringPayment",
"paylinkExpirationPeriod": 7,
"numberOfPayments": null,
"customerId": "d0edbc67-38b9-4ef4-7329-08dc3cbb2fe8",
"number": "453293393959",
"language": "AR",
"agreementId": null,
"merchantName": "",
"amountVariability": "FIXED",
"applePayRecurringToken": null,
"isFirstPmtPBL": true,
"createdDate": "2024-03-08T05:08:46.896845Z",
"createdBy": "DirectApi",
"updatedDate": "2024-03-08T05:08:46.896845Z",
"updatedBy": null
},
"responseCode": "000",
"detailedResponseCode": "000"
}
After you successfully execute the Subscription API request, you must initiate the Create Session API call. This call must contain the subscriptionId
parameter that is generated from the Create Subscription API call.
After you receive the session ID in the response, you should use it to load the HPP (Hosted Payment Page).
The HPP will display a message the following message for the customer.
By clicking 'Pay', you are agreeing that your upcoming payments will be charged automatically from your card.
Once the customer enters the card details and completes the transaction, you'll receive a callback response with the subscription details. Below is the sample callback for reference.
Sample Callback
{
"order": {
"orderId": "177d7d8b-4668-4089-dc9b-08dc3bde4c14",
"amount": 100,
"tipAmount": 0,
"convenienceFeeAmount": 0,
"totalAmount": 100,
"settleAmount": 99.05,
"currency": "AED",
"settleCurrency": "SAR",
"language": "en",
"detailedStatus": "Paid",
"status": "Success",
"threeDSecureId": "67ddfa06-a883-4d83-f4a9-08dc3bde571d",
"merchantId": "d975d546-b7c4-4ac0-1b0c-08db1e9e56b4",
"merchantPublicKey": "d9fd2b48-16f6-4213-9d39-293139dc2795",
"parentOrderId": null,
"merchantReferenceId": null,
"mcc": "1731",
"callbackUrl": "https://webhook.site/77075b05-601f-46e4-9747-ee42c03f9c32",
"billingAddress": {
"countryCode": null,
"street": null,
"city": null,
"postCode": null
},
"shippingAddress": {
"countryCode": null,
"street": null,
"city": null,
"postCode": null
},
"returnUrl": null,
"cardOnFile": true,
"tokenId": "d82eb2d4-8c16-452a-093f-08dc3d100b9e",
"initiatedBy": "Internet",
"agreementId": "0f22da86-6667-4c23-aadb-4d496217b47b",
"agreementType": "Recurring",
"amountVariability": "FIXED",
"paymentOperation": "Pay",
"custom": null,
"paymentIntent": null,
"restrictPaymentMethods": true,
"paymentMethods": null,
"platform": null,
"statementDescriptor": null,
"description": null,
"setDefaultPaymentMethod": false,
"recurrence": {
"recurrenceId": "a6e48ff6-6df1-4868-d01b-08dc3c614224",
"orderId": "177d7d8b-4668-4089-dc9b-08dc3bde4c14",
"amount": 100,
"currency": "AED",
"cycleInterval": "Day",
"cycleFrequency": 3,
"numberOfPayments": 10,
"startDate": "2024-03-06T00:00:00",
"endDate": "2024-04-05T00:00:00",
"minimumDaysBetweenPayments": 1,
"description": "HSBC-Recurring",
"createdDate": "0001-01-01T00:00:00",
"createdBy": "",
"updatedDate": null,
"updatedBy": null
},
"transactions": [
{
"transactionId": "67ddfa06-a883-4d83-f4a9-08dc3bde571d",
"type": "Authentication",
"status": "Success",
"amount": 100,
"currency": "AED",
"source": "HPP",
"authorizationCode": null,
"rrn": null,
"stan": "0",
"paymentMethod": {
"type": "Card",
"brand": "mastercard",
"cardholderName": "sidra",
"maskedCardNumber": "512345******0008",
"wallet": null,
"expiryDate": {
"month": 10,
"year": 39
},
"sameBank": false,
"issuingCountry": null,
"fundingType": null,
"issuingBank": null,
"cardCategory": null
},
"codes": {
"acquirerCode": null,
"acquirerMessage": null,
"responseCode": "000",
"responseMessage": "Success",
"detailedResponseCode": "000",
"detailedResponseMessage": "The operation was successful"
},
"authenticationDetails": {
"acsEci": "02",
"authenticationToken": "kHyn+7YFi1EUAREAAAAvNUe6Hv8=",
"paResStatus": null,
"veResEnrolled": null,
"xid": "44cb9b15-ef86-446e-90b8-c9d1549e1de9",
"accountAuthenticationValue": null,
"proofXml": null,
"threeDSecureServerTransactionId": null,
"acsTransactionId": "3ddaa001-48ae-44fd-9f1d-4eaf3ff6e0a8",
"directoryServerId": "A999999999",
"dsTransactionId": "44cb9b15-ef86-446e-90b8-c9d1549e1de9",
"methodCompleted": true,
"methodSupported": "SUPPORTED",
"protocolVersion": "2.1.0",
"requestorId": "MAS00001_INT_MPGS_MTTESTENDAVA",
"requestorName": "Endava",
"transactionStatus": "Y",
"statusReasonCode": null,
"acsReferenceNumber": null,
"dsReferenceNumber": null
},
"postilionDetails": null,
"terminalDetails": null,
"meezaDetails": null,
"bnplDetails": null,
"bankInstallmentDetails": null,
"correlationId": "3c278279-79af-4a36-8567-06fc9e8560c8",
"parentTransactionId": null,
"paymentAttemptId": "ce7ea410-f179-4af3-aded-e3b30388ff5e",
"acquirer": {
"additionalResponseData": null,
"batch": null,
"customData": null,
"date": null,
"id": null,
"merchantId": "3000000023",
"settlementDate": null,
"time": null,
"timeZone": null,
"transactionId": null
},
"authorizationResponse": {
"autoExpiry": null,
"avsCode": null,
"cardLevelIndicator": null,
"cardSecurityCodeError": null,
"cardSecurityCodePresenceIndicator": null,
"commercialCard": null,
"commercialCardIndicator": null,
"financialNetworkCode": null,
"financialNetworkDate": null,
"marketSpecificData": null,
"merchantAdviceCode": null,
"paySvcData": null,
"posData": null,
"posEntryMode": null,
"posEntryModeChanged": null,
"processingCode": null,
"responseCode": null,
"date": null,
"responseMessage": null,
"returnAci": null,
"time": null,
"timeZone": null,
"trackQuality": null,
"transactionIdentifier": null,
"transactionIntegrityClass": null,
"validationCode": null,
"vpasResponse": null
},
"madaDetails": null,
"refundType": null,
"refundStatus": null,
"isExtensionComplete": null,
"extensionDate": "2024-03-06T08:21:20.9149799",
"deviceId": "2edfe36d-50da-4b38-fe7d-08dc30686a04",
"createdDate": "2024-03-06T08:20:58.6004229",
"createdBy": "PGW",
"updatedDate": "2024-03-06T08:21:20.9154119",
"updatedBy": "PGW"
},
{
"transactionId": "affed950-ac25-4357-f4aa-08dc3bde571d",
"type": "Pay",
"status": "Success",
"amount": 100,
"currency": "AED",
"source": "HPP",
"authorizationCode": "217841",
"rrn": "406608217841",
"stan": "217841",
"paymentMethod": {
"type": "Card",
"brand": "mastercard",
"cardholderName": "sidra",
"maskedCardNumber": "512345******0008",
"wallet": null,
"expiryDate": {
"month": 10,
"year": 39
},
"sameBank": false,
"issuingCountry": null,
"fundingType": null,
"issuingBank": null,
"cardCategory": null
},
"codes": {
"acquirerCode": "00",
"acquirerMessage": "Approved",
"responseCode": "000",
"responseMessage": "Success",
"detailedResponseCode": "000",
"detailedResponseMessage": "The operation was successful"
},
"authenticationDetails": null,
"postilionDetails": null,
"terminalDetails": null,
"meezaDetails": null,
"bnplDetails": null,
"bankInstallmentDetails": null,
"correlationId": "848b28be-e2e6-4fa4-9a35-0d3e89b4ee87",
"parentTransactionId": null,
"paymentAttemptId": "ce7ea410-f179-4af3-aded-e3b30388ff5e",
"acquirer": {
"additionalResponseData": null,
"batch": 20240306,
"customData": null,
"date": "0306",
"id": "RIYADBANK_S2I",
"merchantId": "3000000023",
"settlementDate": "2024-03-06T00:00:00",
"time": null,
"timeZone": "+0300",
"transactionId": "123456789"
},
"authorizationResponse": {
"autoExpiry": null,
"avsCode": null,
"cardLevelIndicator": null,
"cardSecurityCodeError": "M",
"cardSecurityCodePresenceIndicator": null,
"commercialCard": "888",
"commercialCardIndicator": "3",
"financialNetworkCode": "777",
"financialNetworkDate": null,
"marketSpecificData": null,
"merchantAdviceCode": null,
"paySvcData": null,
"posData": "1024100006600",
"posEntryMode": "812",
"posEntryModeChanged": null,
"processingCode": "003000",
"responseCode": "00",
"date": null,
"responseMessage": null,
"returnAci": null,
"time": null,
"timeZone": null,
"trackQuality": null,
"transactionIdentifier": "123456789",
"transactionIntegrityClass": null,
"validationCode": null,
"vpasResponse": null
},
"madaDetails": null,
"refundType": null,
"refundStatus": null,
"isExtensionComplete": null,
"extensionDate": "2024-03-06T08:21:27.5033056Z",
"deviceId": "2edfe36d-50da-4b38-fe7d-08dc30686a04",
"createdDate": "2024-03-06T08:21:22.8001357",
"createdBy": "PGW",
"updatedDate": "2024-03-06T08:21:27.5038456Z",
"updatedBy": "PGW"
}
],
"orderItems": [],
"isTokenPayment": false,
"paymentMethod": {
"type": "Card",
"brand": "mastercard",
"cardholderName": "sidra",
"maskedCardNumber": "512345******0008",
"wallet": null,
"expiryDate": {
"month": 10,
"year": 39
},
"sameBank": false,
"issuingCountry": null,
"fundingType": null,
"issuingBank": null,
"cardCategory": null
},
"totalAuthorizedAmount": 100,
"totalCapturedAmount": 100,
"totalRefundedAmount": 0,
"orderSource": "GeideaGateway",
"paymentBrands": [
"mastercard"
],
"multiCurrency": {
"authCurrency": "AED",
"authAmount": 100,
"settleCurrency": "SAR",
"settleAmount": 99.05,
"exchangeRate": 1.0211,
"exchangeFeePercentage": 3,
"exchangeFeeAmount": 3.06
},
"isTest": true,
"cashOnDelivery": false,
"amountToCollect": null,
"isDownPayment": false,
"exchangeRate": 1.0211,
"exchangeFeePercentage": 3,
"exchangeFeeAmount": 3.06,
"deviceId": "2edfe36d-50da-4b38-fe7d-08dc30686a04",
"gatewayDecision": "ContinueToPay",
"subscriptionId": "5390116f-fc3b-4d60-db4e-08dc3c4cda87",
"subscriptionOccurrenceId": "63d60ed9-95be-42ba-ae2a-08dc3c4cda89",
"refundType": null,
"refundStatus": null,
"bankId": null,
"isPayWithToken": false,
"customerName": null,
"customerEmail": null,
"createCustomer": false,
"customerReferenceId": null,
"customerId": null,
"customerPhoneNumber": null,
"customerPhoneCountryCode": null,
"customerCustomValue": null,
"airLine": null,
"createdDate": "2024-03-06T08:20:58.6004229",
"createdBy": "PGW",
"updatedDate": "2024-03-06T08:21:08.0478995",
"updatedBy": "PGW"
},
"signature": "4y8wYhOV+3SWxi9LGMR2hnPgK+EDTqXYqvXwYLO7yWM=",
"timeStamp": "03/06/2024 08:21:27"
}
Once the transaction is successfully approved the customer receives an email with the subscription details.
Sample email sent to the customer
Updated 3 months ago