There are two ways for integrators to track recurring payments being processed by PayJunction in a merchant's account:
- Consuming transaction webhooks and checking the transaction data for a scheduleId property (recommended)
- Perform a transaction search with the scheduleId query parameter
Webhooks
The following is a summary of the workflow for tracking recurring transactions. For more information on working with webhooks in general, please see the Webhooks section of the API documentation.
In order to track recurring payments in real time, and avoid busy polling, it is recommended to consume transaction webhooks and check each new transaction for a scheduleId property.
Step 1: Subscribe to the TRANSACTION webhook
The TRANSACTION webhook is triggered on all transactions that are processed in a merchant's account, including recurring transactions. To subscribe to the TRANSACTION webhook, perform a POST request to the /webhooks endpoint with event=TRANSACTION as documented here.
Step 2: Consume incoming webhooks
For security, the data sent by incoming webhooks does not contain transaction data. Rather, it provides the information needed for the integrated software to securely fetch this data from the PayJunction API:
{ "id" : "8611ac99-79c2-4276-8aae-47ebb63a6ba2", "created" : "2022-05-03T20:16:32.097Z", "type" : "TRANSACTION", "data" : { "transactionId" : 9035 } }
We will need to capture the transactionId property in order to fetch the transaction details from the PayJunction API.
Step 3: Fetch the transaction data
With the transactionId captured in the previous step we can then perform a GET request to the /transactions endpoint as described here.
Example Response
{ "transactionId": 9035, "uri": "https://api.payjunctionlabs.com/transactions/9035", "terminalId": 11495, "scheduleId": 57, "action": "CHARGE", "amountBase": "10.00", "amountTotal": "10.00", "invoiceNumber": "123456", "custom1": "SKU #", "method": "INSTANT", "service": "VIRTUAL_TERMINAL", "status": "CAPTURE", "signatureStatus": "PENDING", "created": "2022-05-03T20:16:32Z", "lastModified": "2022-05-03T20:16:32Z", "response": { "approved": true, "code": "00", "message": "Approved", "processor": { "authorized": true, "approvalCode": "PJ20AP", "avs": { "status": "REQUESTED", "requested": "BYPASS", "match": { "ZIP": true, "ADDRESS": false } }, "cvv": { "status": "NOT_REQUESTED" } } }, "settlement": { "settled": false }, "vault": { "type": "CARD", "accountType": "VISA", "lastFour": "1111" }, "billing": { "email": "person@example.com", "address": { "address": "123 East Micheltorena Street", "city": "Santa Barbara", "state": "CA", "country": "US", "zip": "93101" } } }
Having confirmed the existence of the scheduleId property in the transaction details, the integrated software can use its value to cross reference the schedule and customer internally.
For integrations on API version 2020-04-13 and above, a service property is returned in the API data. This property indicates which service initiated the transaction. Therefore, while transactions processed automatically as part of the schedule will show "service": "RECURRING", if a merchant triggers a manual payment on the schedule via the Virtual Terminal web portal it would have a scheduleId but the service property will be VIRTUAL_TERMINAL, not RECURRING, as shown in the example above.
Transaction Search
In cases where consuming webhooks is not feasible, such as on-prem setups, an integrated application can instead perform periodic transaction searches to sync their records with PayJunction.
For general, periodic syncing, it is recommended to perform a GET /transactions request and iterate through the results, checking for the _scheduleId_ property. To sync a specific recurring schedule, such as per an end user request, a GET /transactions?scheduleId={scheduleId} request can be performed for greater efficiency.
For more details on transaction searches with query parameters please see our documentation here.
Example Response
{ "next": "https://api.payjunctionlabs.com/transactions/?offset=2&limit=2&scheduleId=57", "results": [ { "transactionId": 9035, "uri": "https://api.payjunctionlabs.com/transactions/9035", "terminalId": 11495, "scheduleId": 57, "action": "CHARGE", "amountBase": "10.00", "amountTotal": "10.00", "invoiceNumber": "123456", "custom1": "SKU #", "method": "INSTANT", "service": "VIRTUAL_TERMINAL", "status": "CAPTURE", "signatureStatus": "PENDING", "created": "2022-05-03T20:16:32Z", "lastModified": "2022-05-03T20:16:32Z", "response": { "approved": true, "code": "00", "message": "Approved", "processor": { "authorized": true, "approvalCode": "PJ20AP", "avs": { "status": "REQUESTED", "match": { "ZIP": true } }, "cvv": { "status": "NOT_REQUESTED" } } }, "settlement": { "settled": false }, "vault": { "type": "CARD", "accountType": "VISA", "lastFour": "1111" }, "billing": { "email": "person@example.com" } }, { "transactionId": 9025, "uri": "https://api.payjunctionlabs.com/transactions/9025", "terminalId": 11495, "scheduleId": 57, "action": "CHARGE", "amountBase": "10.00", "amountTotal": "10.00", "invoiceNumber": "123456", "method": "RECURRING", "service": "RECURRING", "status": "CAPTURE", "created": "2022-04-27T13:15:08Z", "lastModified": "2022-04-27T13:15:07Z", "response": { "approved": true, "code": "00", "message": "Approved", "processor": { "authorized": true, "approvalCode": "PJ20AP", "avs": { "status": "REQUESTED", "match": { "ZIP": true } }, "cvv": { "status": "NOT_REQUESTED" } } }, "settlement": { "settled": true, "settlementId": 1283 }, "vault": { "type": "CARD", "accountType": "VISA", "lastFour": "1111" }, "billing": { "email": "person@example.com" } } ] }