Recurring Transactions
This documentation will cover the creation, query, and deletion of a recurring transaction of fixed $ amount.
Info
If a scheduled payment of a recurring transaction fails (including the first payment on startDate), the recurring transaction is halted: the order is marked as failed (status = 9), a failed notification is sent, and no further payments will be made. A halted recurring transaction is not cancelled, and is still returned by the query endpoints with last_payment set to the failed order. Use the cancel endpoint to stop a recurring transaction, and create a new one to resume charging the customer.
Creating Recurring Payment
Endpoint
https://ccapi.iotpaycloud.com/v3/recurring/create
Method:
POST
Header
Content-Type: application/json;charset=UTF-8
Important
If startDate is not included in the request: a startDate of the current date will be configured for this subscription and a payment will be made immediately with proceeding payments following the recurring frequency. If this first payment fails, no recurring transaction is created, retCode will be FAIL and retData will contain the failed order (status = 9).
If startDate is included in the request: no payment is made at creation. The first payment will be made on startDate (UTC), and retData will contain the pending order (status = 0) without payment details.
Request
| Name | Required | Type | Sample | Description |
|---|---|---|---|---|
| mchId | y | String | 10000701 | Assigned by IOTPay |
| mchOrderNo | y | String(50) | 1234567890abc | Assigned by merchant, must be unique per merchant |
| cardId | y | String(50) | The cardId used for the add card endpoints (direct, redirect). | |
| frequency | y | String | [w,2w,4w,m] | Current possible configurations are w (weekly), 2w (bi-weekly), 4w (every 4 weeks, 28 days) or m (monthly, set day each given month) |
| startDate | n | Int | 1798761600 | The UNIX timestamp (seconds) for the first recurring payment; ie. 1798761600 => Fri Jan 01 2027 00:00:00 GMT+0000. Must be a date after the current UTC date and within 10 years. The first payment is made immediately if startDate not supplied |
| amount | y | Int | 1500 | In cents, must > 0 |
| currency | y | String(3) | CAD | Fixed to: CAD |
| loginName | y | String(12) | jack123 | Merchant's login name |
| notifyUrl | y | String(200) | http://sample.com/notify | Merchant endpoint for receiving recurring payment notifications, must be http or https |
| description | n | String(200) | Test recurring order. | Optional description for the recurring transaction |
| sign | y | String(32) | Sign algorithm |
Response
| name | required | type | sample | description |
|---|---|---|---|---|
| retCode | y | String | SUCCESS or FAIL | |
| retMsg | y | String | Failed reason displayed here | |
| retData | y | JSON | If retCode=SUCCESS, order detailed info returned |
retData contains order information:
| name | required | type | sample | description |
|---|---|---|---|---|
| payOrderId | y | String | Pay order Id of the first order of this recurring transaction | |
| mchId | y | String | Your merchant Id | |
| mchOrderNo | y | String | Should match request mchOrderNo | |
| currency | y | String | CAD | |
| amount | y | Int | 100 | In cents, matching request amount |
| payType | y | String | pay | Fixed to pay |
| refundable | y | Int | 100 | In cents, matching amount |
| status | y | Int | 0,2,3 | 0 = pending order (startDate supplied, first payment not made yet), 2 or 3 = success |
| invoiceNum | n | String | Not returned if startDate supplied | |
| paySuccTime | n | String | 2021-04-07 19:44:51 | Timestamp of the successful payment. Not returned if startDate supplied |
| authNum | n | String | Not returned if startDate supplied | |
| transNum | n | String | Not returned if startDate supplied | |
| channel | y | String | PF_CC | Fixed to PF_CC |
| recurringId | y | Int | 123 | Id of the newly created recurring payment, used by the query and cancel endpoints |
| cardId | y | String(50) | Should match request cardId | |
| notifyUrl | y | String(200) | http://sample.com/notify | Supplied notifyUrl, should match request notifyUrl |
| frequency | y | String | [w,2w,4w,m] | Should match request frequency |
| startDate | y | String | 2027-01-01 | Date of the first payment in UTC time (YYYY-MM-DD) |
| nextPayment | y | String | 2027-01-08 | Date of the next scheduled payment in UTC time (YYYY-MM-DD), same as startDate if startDate supplied |
| description | n | String(200) | Test recurring order. | Optional description for the recurring transaction, should match request description |
Query Recurrings by Id
Responds with the exact recurring payment with the matching recurringId, along with a paginated list of the orders it has made
Endpoint
https://ccapi.iotpaycloud.com/v3/recurring/query
Method:
POST
Header
Content-Type: application/json;charset=UTF-8
Request
| name | required | type | sample | description |
|---|---|---|---|---|
| mchId | y | String | 10000701 | Assigned by IOTPay |
| loginName | y | String(12) | jack123 | Merchant's login name |
| recurringId | y | Int | 123 | The recurringId returned by the (create recurring endpoint). |
| page | n | Int | 1 | Page number of orders to return, defaults to 1 |
| pageSize | n | Int | 20 | Number of orders per page, defaults to 20, max 100 |
| sign | y | String(32) | Sign algorithm |
Response
| name | required | type | sample | description |
|---|---|---|---|---|
| retCode | y | String | SUCCESS or FAIL | |
| retMsg | y | String | ||
| retData | y | JSON | If retCode is SUCCESS, the recurring payment detail be returned |
retData contains the following recurring information:
| name | required | type | sample | description |
|---|---|---|---|---|
| id | y | Int | 123 | The recurring Id |
| amount | y | Int | 100 | In cents |
| mid | y | String | Merchant id | |
| currency | y | String | CAD | Fixed to CAD |
| start_date | y | String | 2027-01-01 | Payment start date in UTC time (YYYY-MM-DD) |
| frequency | y | String | [w,2w,4w,m] | Current possible configurations are w (weekly), 2w (bi-weekly), 4w (every 4 weeks, 28 days) or m (monthly, set day each given month) |
| description | n | String(200) | Test recurring order. | Optional description for the recurring transaction |
| last_paid | y | String | 2027-01-01 | Last successful payment date in UTC time (YYYY-MM-DD), defaults to "1970-01-01" if no payment has succeeded yet |
| last_payment | y | String | Payorderid of the last payment, successful or failed, or of the pending first order if no payment has been made yet | |
| next_payment | y | String | 2027-01-08 | Date of next scheduled payment in UTC time (YYYY-MM-DD). If the last payment failed, stays at the date of that payment and no further payment will be made |
| cardId | y | String(50) | The cardId associated with this recurring payment | |
| orders | y | JSON | Paginated list of the orders made by this recurring payment, newest first |
orders contains the following pagination information:
| name | required | type | sample | description |
|---|---|---|---|---|
| page | y | Int | 1 | Current page number |
| pageSize | y | Int | 20 | Number of orders per page |
| total | y | Int | 45 | Total number of orders made by this recurring payment |
| lastPage | y | Int | 3 | Last page number |
| list | y | List | Orders on the current page, empty if page is greater than lastPage |
Each JSON object in orders.list contains the following order information:
| name | required | type | sample | description |
|---|---|---|---|---|
| payOrderId | y | String | Id assigned by IOTPay | |
| mchId | y | String | Your merchant Id | |
| mchOrderNo | y | String | The request mchOrderNo for the first order, same as payOrderId for the following orders | |
| originalOrderId | y | String | Pay order Id of the previous order of this recurring payment, empty for the first order | |
| currency | y | String | CAD | |
| amount | y | Int | 100 | In cents |
| payType | y | String | pay | Fixed to pay |
| refundable | y | Int | 100 | In cents |
| status | y | Int | 0,1,2,3,9 | 0 = pending order, 1 = unknown, 2 or 3 = success, 9 = fail |
| invoiceNum | y | String | ||
| paySuccTime | y | String | 2021-04-07 19:44:51 | Timestamp of the successful payment, empty if the order has not been paid |
| authNum | y | String | ||
| transNum | y | String | ||
| channel | y | String | PF_CC | Fixed to PF_CC |
| recurringId | y | Int | 123 | Should match request recurringId |
| capture | n | String | Y | Fixed to Y |
| notifyUrl | y | String(200) | http://sample.com/notify | The notifyUrl supplied when creating the recurring payment |
Query Recurrings by CardId
List all the recurring payments for the customer with provided cardId
Endpoint
https://ccapi.iotpaycloud.com/v3/recurring/query_by_card
Method:
POST
Header
Content-Type: application/json;charset=UTF-8
Request
| name | required | type | sample | description |
|---|---|---|---|---|
| mchId | y | String | 10000701 | Assigned by IOTPay |
| loginName | y | String(12) | jack123 | Merchant's login name |
| cardId | y | String(50) | The cardId used for the add card endpoints (direct, redirect). | |
| sign | y | String(32) | Sign algorithm |
Response
| name | required | type | sample | description |
|---|---|---|---|---|
| retCode | y | String | SUCCESS or FAIL | |
| retMsg | y | String | ||
| retData | y | List | If retCode is SUCCESS, a list of recurring payment(s) that used the cardId as the payment method will be returned (empty list if none) |
Each JSON object in retData contains the following recurring information:
| name | required | type | sample | description |
|---|---|---|---|---|
| id | y | Int | 123 | The recurring Id |
| amount | y | Int | 100 | In cents |
| mid | y | String | Merchant id | |
| currency | y | String | CAD | Fixed to CAD |
| start_date | y | String | 2027-01-01 | Payment start date in UTC time (YYYY-MM-DD) |
| frequency | y | String | [w,2w,4w,m] | Current possible configurations are w (weekly), 2w (bi-weekly), 4w (every 4 weeks, 28 days) or m (monthly, set day each given month) |
| description | n | String(200) | Test recurring order. | Optional description for the recurring transaction |
| last_paid | y | String | 2027-01-01 | Last successful payment date in UTC time (YYYY-MM-DD), defaults to "1970-01-01" if no payment has succeeded yet |
| last_payment | y | String | Payorderid of the last payment, successful or failed, or of the pending first order if no payment has been made yet | |
| next_payment | y | String | 2027-01-08 | Date of next scheduled payment in UTC time (YYYY-MM-DD). If the last payment failed, stays at the date of that payment and no further payment will be made |
| cardId | y | String(50) | Should match the given cardId in the request |
Cancel Recurring Payment
To stop a recurring transaction. No further payments will be made, and the cancelled recurring payment will no longer be returned by the query endpoints
Endpoint
https://ccapi.iotpaycloud.com/v3/recurring/cancel
Method:
POST
Header
Content-Type: application/json;charset=UTF-8
Request
| name | required | type | sample | description |
|---|---|---|---|---|
| mchId | y | String | 10000701 | assigned by IOTPay |
| loginName | y | String(12) | jack123 | merchant's login name |
| recurringId | y | Int | 123 | recurring payment id returned by the (create recurring endpoint) |
| sign | y | String(32) | Sign algorithm |
Response
| name | required | type | sample | description |
|---|---|---|---|---|
| retCode | y | String | SUCCESS or FAIL | |
| retMsg | y | String | Successfully deleted recurring #255 | |
| retData | y | JSON | if retCode is SUCCESS, recurring payment detailed info returned |
retData contains recurring information:
| name | required | type | sample | description |
|---|---|---|---|---|
| id | y | Int | 123 | The recurring Id |
| amount | y | Int | 100 | In cents |
| mid | y | String | Merchant id | |
| currency | y | String | CAD | Fixed to CAD |
| start_date | y | String | 2027-01-01 | Payment start date in UTC time (YYYY-MM-DD) |
| frequency | y | String | [w,2w,4w,m] | Current possible configurations are w (weekly), 2w (bi-weekly), 4w (every 4 weeks, 28 days) or m (monthly, set day each given month) |
| description | n | String(200) | Test recurring order. | Optional description for the recurring transaction |
| last_paid | y | String | 2027-01-01 | Last successful payment date in UTC time (YYYY-MM-DD), defaults to "1970-01-01" if no payment has succeeded yet |
| last_payment | y | String | Payorderid of the last payment, successful or failed, or of the pending first order if no payment has been made yet | |
| next_payment | y | String | 2027-01-08 | Date of next scheduled payment in UTC time (YYYY-MM-DD). If the last payment failed, stays at the date of that payment and no further payment will be made |
| cardId | y | String(50) | The cardId associated with this recurring payment |
Recurring Payment Notification
After each payment of a recurring transaction, IOTPay will send a notification to the notifyUrl supplied in the create request. This includes the first payment when startDate is not supplied (only if it succeeds), and every scheduled payment afterwards (whether it succeeds or not). A failed payment halts the recurring transaction, so a failed notification is the last one sent for it.
Important
Respond with the plain text SUCCESS once the notification is received. Otherwise, the notification will be sent again, up to 3 times in total, 60 seconds apart.
Method:
POST
Header
Content-Type: application/json;charset=UTF-8
Request
| name | required | type | sample | description |
|---|---|---|---|---|
| payOrderId | y | String | Pay order Id of this payment | |
| mchOrderId | y | String | The request mchOrderNo for the first payment, same as payOrderId for the following payments | |
| channel | y | String | PF_CC | Fixed to PF_CC |
| amount | y | Int | 1500 | In cents |
| status | y | String | success | success means the payment went through; failed means it did not and the recurring transaction is halted. Treat any other value (pending, paying, returned) as not paid |
| recurringId | y | Int | 123 | Recurring payment id this payment belongs to |
| previousOrder | y | String | Pay order Id of the previous order of this recurring payment, empty for the first payment | |
| paySuccessTime | n | String | 2021-04-07 19:44:51 | Timestamp of the successful payment, only included if the payment went through |
| sign | y | String(32) | Verify with the Sign algorithm using your merchant key |
