Submit a ticket My tickets Knowledge Base API Reference
Welcome
Login  Sign up
Open navigation

Enterprise with Scheduler Integration Guide

TABLE OF CONTENTS

Introduction

The purpose of this document is to provide technical details regarding an integration to Flexpay using the scheduled Auto-Retries feature. This feature allows you to send transaction details to FlexPay via individual API calls. FlexPay then takes over the retry process by scheduling and triggering the retry attempts. 

Requirements

To benefit from FlexPay’s Enterprise with Scheduler API integration, you will need the following:

  • FlexPay Production account
  • At least one Company configured in the account (There is a default company) Learn more
  • Payment gateways configured for each Company Learn more
  • FlexPay Retries configured for each Company Learn more
  • Production API keys for each Company Learn more
  • Ability to POST a request to the Charge endpoint Learn more
  • Ability to POST a request to the Redact/Refund endpoint Learn more
  • Ability to send a request to the GET Transaction List endpoint Learn more

Process Flow

  1. A subscription rebill is sent directly to the gateway. It declines.
  2. It is then rerouted & scheduled to be sent through FlexPay.
  3. 24 hours after the initial rebill failure, a Charge is sent to FlexPay 
  4. FlexPay analyses the payload and determines whether to send the request to the gateway.
  5. FlexPay analyses the response from the gateway. If it’s a soft decline, a retry is scheduled for a future date. FlexPay continues this process until one of the following events takes place:
    1. The transaction approves.
    2. The transaction hard declines.
    3. A configuration limit is reached. Maximum 15 retries or 30 days, whichever is reached first.
  6. To determine the status of transactions in recovery, the system of record sends a request for the list of all transactions in a given time frame.
  7. To stop the recovery process, (for example, if a customer cancels their subscription) the system of record sends a Refund-Payment request to FlexPay.

How-To

Send a transaction to FlexPay

Before sending a transaction to FlexPay, a payment gateway must be configured under a Company. It must include the merchant account’s credentials so FlexPay can connect on your behalf.

Gateway Management API

API reference: Gateway Management API

Using the Gateway Management API is the most reliable way to create and update a gateway in our system. Once created, you can use the merchantAccountReferenceId or the gatewayToken values to send a transaction to the appropriate gateway in FlexPay. Gateways can also be created manually in the FlexPay client portal. If you only have a small number if merchant accounts, this may be the easiest way to create the payment gateways in FlexPay.

Charge

API reference: Charge Request

Sending a transaction to FlexPay’s scheduler is the same as sending a transaction using our standard Enterprise integration. The difference is in the configuration of the account in FlexPay’s admin and client portal. When you first send a Charge request, FlexPay will evaluate and process the transaction synchronously. You can expect the response to take only a few hundred milliseconds more than your usual gateway transaction time. Authorize and Capture are not supported for Enterprise with Scheduler.

Note: you are not simply sending us the transaction data for FlexPay to process asynchronously. More often than not, we will process the transaction immediately and return a response that includes the result from your gateway. It is up to you whether to ingest the result of this response or wait for the next GET Transaction List request.

Once we receive the transaction, if we return a retry date, it is now in the FlexPay scheduler and will follow the recovery process. FlexPay will determine the next retry date and trigger any future transactions. If FlexPay has decided not to retry the transaction, we will return null in the retryDate field. You can look at FlexPay’s responseCode and message to determine the reason. 

Get the status of transactions

Transactions List

API reference: List Request

To know the status of a transaction, you must send a GET request to receive a single transaction or a list of transactions that were processed in a specific time period. FlexPay recommends a daily request to receive details from the previous (or current) calendar day. 

There are several parameters that can be configured when requesting a list of transactions.’

Params

Description

order

The sorting order of the returned list. The default is asc, which returns the oldest records first. To list newer records first, use desc.

sinceTransactionId

The transaction id of the item to start from (e.g., the last transaction id received in the previous list if iterating through records)

By default, unbounded lists are returned in groups of 20 items. If there are more than 20 items in the list, use pagination to retrieve the next set of 20. To enforce determinism in a real-time system, pagination is indexed based on a specific record (as opposed to just a page number as is common in many web apps). To paginate to the next page, simply pass in the transactionId of the last record in the current result set. For instance, if the transactionId of the last transaction in the initial set of twenty transactions returned is JZE57KX6PMSU7MZLAFNIBQWJEQ, use that as the sinceTransactionId parameter to get the next set of 20 starting after that gateway.

completedOnly

Request a list of transactions that have completed the recovery process.

Note: If this parameter is not provided or null, response will return all transactions (Default/Current behavior).

responseType

Request the simplified or detailed (Default) response. 

count

The number of transactions to return. By default, returns 20, maximum allowed is 100.

startDate

Date range start of the returned list (Format: YYYY-MM-DD)

endDate

Date range end of the returned list (Format: YYYY-MM-DD). To receive transactions from the current day, set this value to a future date (e.g. tomorrow).

Note: FlexPay timestamps are all in UTC.
► Simplified Response Sample
{
    "transactions": [
        {
            "transactionId": "065RCDZZ4800000G002M71YGY3M4R",
            "transactionDate": "2023-10-31T14:51:38.658Z",
            "transactionStatus": 2,
            "message": "'MerchantTransactionReferenceId' and 'CustomerReferenceId' Required.",
            "transactionType": "Refund",
            "retryDate": null,
            "amount": 1050,
            "initialMerchantTransactionId ": "839BA292-C385-4A84-BB49-6E58118CD1BE638342846590759466638343606986743642",
            "paymentMethodStorageState": "Cached",
            "completionStatus": "RefundUnsuccessful"
        },
        {
            "transactionId": "065RCDVAM000000G002QH1E25N1JM",
            "transactionDate": "2023-10-31T14:51:00.64Z",
            "transactionStatus": 2,
            "message": "Original payment not found using the field 'MerchantTransactionReferenceId'.",
            "transactionType": "Refund",
            "retryDate": null,
            "amount": 1050,
            "initialMerchantTransactionId ": "839BA292-C385-4A84-BB49-6E58118CD1BE638343603538821648",
            "paymentMethodStorageState": "Redacted",
            "completionStatus": "RefundUnsuccessful"
        },
        {
            "transactionId": "065RCDF07R00000G002C0PGQ8MMGC",
            "transactionDate": "2023-10-31T14:49:19.678Z",
            "transactionStatus": 2,
            "message": "DO NOT RETRY - System error",
            "transactionType": "Charge",
            "retryDate": null,
            "amount": 1050,
            "initialMerchantTransactionId ": "839BA292-C385-4A84-BB49-6E58118CD1BE638343603538821648",
            "paymentMethodStorageState": "Redacted",
            "completionStatus": "RecoveryUnsuccessful"
        },
        {
            "transactionId": "065RCC6TM800000G002HSHS3A3FSA",
            "transactionDate": "2023-10-31T14:43:50.562Z",
            "transactionStatus": 2,
            "message": "Original payment not found using the field 'MerchantTransactionReferenceId'.",
            "transactionType": "Refund",
            "retryDate": null,
            "amount": 1050,
            "initialMerchantTransactionId ": "839BA292-C385-4A84-BB49-6E58118CD1BE638343600911685741",
            "paymentMethodStorageState": "Redacted",
            "completionStatus": "RecoveryCancelled"
        },
        {
            "transactionId": "065RCB6TM400000G002WGPSZQHKXC",
            "transactionDate": "2023-10-31T14:39:28.417Z",
            "transactionStatus": 2,
            "message": "Cannot refund this payment already refunded.",
            "transactionType": "Refund",
            "retryDate": null,
            "amount": 1050,
            "initialMerchantTransactionId ": "839BA292-C385-4A84-BB49-6E58118CD1BE638343595687306493",
            "paymentMethodStorageState": "Redacted",
            "completionStatus": "RefundUnsuccessful"
        },
        {
            "transactionId": "065RCB3D8R00000G002QZ6AHQM06P",
            "transactionDate": "2023-10-31T14:39:00.422Z",
            "transactionStatus": 1,
            "message": "Approved.",
            "transactionType": "Refund",
            "retryDate": null,
            "amount": 1050,
            "initialMerchantTransactionId ": "839BA292-C385-4A84-BB49-6E58118CD1BE638343595687306493",
            "paymentMethodStorageState": "Redacted",
            "completionStatus": "Refunded"
        },
        {
            "transactionId": "065RCATCE400000G00208H9NEVSBY",
            "transactionDate": "2023-10-31T14:37:46.481Z",
            "transactionStatus": 1,
            "message": "Approved.",
            "transactionType": "Charge",
            "retryDate": null,
            "amount": 1050,
            "initialMerchantTransactionId ": "839BA292-C385-4A84-BB49-6E58118CD1BE638343595687306493",
            "paymentMethodStorageState": "Redacted",
            "completionStatus": "RecoverySuccessful"
        }
}
► Detailed Response Sample
"transactions": [
        {
            "acquirerAuthCode": null,
            "responseCode": "50163",
            "gatewayTransactionId": null,
            "gatewayPaymentMethodId": null,
            "engagedRecoveryState": 0,
            "currencyCode": "USD",
            "retryDate": null,
            "merchantTransactionId": "01HE3PWTYP72CATMD17R1KTMY7",
            "merchantAccountReferenceId": "1007",
            "initialTransactionId": "065REV18SR00000G0825X82M8GWT6",
            "customerId": "AutoRetrySandboxCustomer 02",
            "orderId": "392E6A9C-AFD9-6533-BE4C-EA0FB7AF6113",
            "paymentMethodId": "VX6L5NIPMHOEDMEOAGFYO3BI7U",
            "paymentMethodStorageState": "Cached",
            "paymentMethodType": "CreditCard",
            "paymentMethodMerchantAccountReferenceId": null,
            "errorCode": null,
            "errorDetail": null,
            "gateway": {
                "token": "P65TO7YCDBRUVHKRER66MWG7PQ",
                "gatewayType": "flexpay_sandbox",
                "name": "QA Flexpay Sandbox",
                "referenceId": "1007"
            },
            "transactionId": "065REWJAHM00000G082YA32GF4TGG",
            "transactionDate": "2023-10-31T20:34:56.269Z",
            "transactionStatus": 2,
            "message": "Original payment not found using the field 'MerchantTransactionReferenceId'.",
            "transactionType": "Refund",
            "amount": 1050,
            "initialMerchantTransactionId ": "909BA272-C385-4A84-BB49-6E53219CD100",
            "completionStatus": "RefundUnsuccessful"
        }
}

For details on pagination, please see the following article.

Payment Status

API reference: Payment Status

The “payment-status” endpoint can be used to check the status of a transaction in recovery. It will return the last transaction processed for the payment in recovery.

Payment Status Example:

{    
"transactionId": "065MV5WGS800000200252K6PHRACW",
"transactionDate": "2023-10-20T14:57:40.554Z",
"transactionStatus": 1,
"completionStatus": "RecoverySuccessful",
"message": "Approved.",
"transactionType": "Charge",
"initialMerchantTransactionId": "802BA292-C385-4A84-BB49-6E58118CD1BE638334106606"
}

The completionStatus field is included in both the detailed and simplified response to provide clarity to clients. This field describes the end-state of a payment. The list of possible values returned in this field are found in the Completion Status Value column below.

Transaction Type

Transaction Status

Payment Method Storage State

Completion Status Value

Charge

Approved

 

 RecoverySuccessful

Refund

Approved

 

 Refunded

Charge

Declined

 

 RecoveryUnsuccessful

Refund

Declined

Redacted

 RecoveryCancelled

Refund

Declined

NOT Redacted

 RefundUnsuccessful

Reconcile with your system

The transaction list and payment status requests will return certain fields that can help with reconciliation. FlexPay recommends using the initialMerchantTransactionId for this purpose. The value of this field was provided by your system when first sending a decline to FlexPay. This will remain consistent for every attempt processed by FlexPay. 

Stop the retry process

There are two ways to stop the retry process via API:

  1. Use the Refund-Payment endpoint. This will Redact or Refund depending on the status of the payment.
  2. Using Redact and Refund separately (alternative methods)

Refund-Payment Endpoint

API reference: Refund-Payment

The “refund-payment” endpoint will refund (if transaction was approved) or redact (if transaction is still in recovery) with a single request.

  • The refund-payment endpoint requires both merchantTransactionId (in the URL) and customerId (in the request body). 
  • The merchantTransactionId sent in the URL can be the initial value sent to Flexpay or any other merchantTransactionId’s from the chain of transactions.
  • The customerId is required and must be send in the request body.
  • Refunds can only be processed for a Maximum of 4 months from the approval date.
  • NOTE: The merchantTransactionId in the request body is not the same as the one sent in the URL. It is a unique values used to reconcile this specific request. It is not required, so the field can be empty (“”), null, or omitted.

Refund-Payment Example:

{
"transaction": {
"merchantTransactionId": "order-123Avc2017-09-20T14:42:49.3003196+00:00",
"customerId": "customer-123"
"disableCustomerRecovery": true,
"amount": 0,
"customVariable1": "var1",
"customVariable2": "var2",
"customVariable3": "var3",
"customVariable4": "var4",
"customVariable5": "var5"
}
}

Redact Payment Method

API reference: Redact

When you send a Charge to FlexPay, we generate and return a value for the paymentMethodId in our response. This value needs to be stored and used in a new request to stop the retry process. 

Using the PUT Redact Payment Method endpoint will remove a customer’s payment method from our system.   This effectively blocks any further transactions done on this card. If it is attempted again, FlexPay will a 50134 Invalid payment method token response. This transaction will not be sent to the gateway.

Refund a transaction

API Reference: Refund

If a payment that was recovered by FlexPay is subsequently refunded, FlexPay will credit the merchant for any fees associated with the recovery. The simplest way to keep track of these refunds is to process them through FlexPay

Sandbox Testing

Typically, the FlexPay enablement team will create a “Sandbox” account for testing. This account has all the same functionality as a production account, so caution must be exercised when configuring the account. Within the test account, FlexPay has a Sandbox environment where you can test the FlexPay Scheduler Auto-retries feature.

The sandbox environment applies to Payment Gateways and API keys. Companies can have both Production and Sandbox API keys associated to them. When you create a Sandbox API Key, you will only be able to create & send requests to payment gateways in the Sandbox environment. Not all gateways are supported in the Sandbox. In the Sandbox Environment, there is a gateway called “FlexPay Sandbox”. This gateway must be used for the testing scenarios described below. 

Please speak to the FlexPay team if you don’t see the FlexPay Sandbox payment gateway available.

Requirements

The requirements for Sandbox testing are similar to those outlined previously in this guide, with two main differences. Instead of a regular FlexPay account, you need a FlexPay Test account, and instead of a regular payment gateway, you need a FlexPay Sandbox gateway. Please work closely with your integration manager to get these provisioned for you.

Use Cases

To simulate different scenarios and ensure your integration is ready for production, validate the following use cases by using the listed retryCount and Amounts.

Use Case 1: Testing Scheduling and Approval (using Credit Card)

  • RetryCount = 0
  • Amount = 9900
  • Flow: 
    1. First transaction (sent by Integration Partner) will Decline and will automatically schedule a Retry (schedule command).
      • Retry will be executed automatically by the auto retry integration within 5-10 minutes.
    2. Second transaction (sent by FlexPay Scheduler) will also Decline and will automatically schedule a Retry (schedule command) 
    3. Third transaction (sent by FlexPay Scheduler) will Approve and there will be no more retries that will be scheduled.

Use Case 2: Testing Scheduling and Approval (using 3rd Party Token)

  • RetryCount = 0
  • Amout = 9900
  • ThirdPartyToken = flexpay_auto_retries_sandbox_soft
    • Example: "gatewayPaymentMethodId": "flexpay_auto_retries_sandbox_soft"
  • Flow: 
    1. First transaction (sent by Integration Partner) will Decline and will automatically schedule a Retry (schedule command).
      • Retry will be executed automatically by the auto retry integration within 5-10 minutes.
    2. Second transaction (sent by FlexPay Scheduler) will also Decline and will automatically schedule a Retry (schedule command) 
    3. Third transaction (sent by FlexPay Scheduler) will Approve and there will be no more retries that will be scheduled.

Use Case 3: Testing Scheduling and Hard Decline (using Credit Card)

  • RetryCount = 0
  • Amount = 9910
  • Flow: 
    1. First transaction (sent by Integration Partner) will Decline and will automatically schedule a Retry (schedule command).
      • Retry will be executed automatically by the auto retry integration within 5-10 minutes.
    2. Second transaction (sent by FlexPay Scheduler) will Hard Decline and there will be no more retries that will be scheduled.

Use Case 4: Testing Scheduling and Hard Decline (using 3rd Party Token)

  • RetryCount = 0
  • Amount = 9100
  • ThirdPartyToken = flexpay_auto_retries_sandbox_hard
    • Example: "gatewayPaymentMethodId": "flexpay_auto_retries_sandbox_hard"
  • Flow: 
    1. First transaction (sent by Integration Partner) will Decline and will automatically schedule a Retry (schedule command).
      • Retry will be executed automatically by the auto retry integration within 5-10 minutes.
    2. Second transaction (sent by FlexPay Scheduler) will Hard Decline and there will be no more retries that will be scheduled.

Use Case 5: Testing a Redact/Refund request for an Approval

  • Using the merchantTransactionId and customerId from Use Case 1 or 2, send a Refund-Payment POST request.
  • This transaction should be sent after the approved attempt has occurred. 

Use Case 6: Testing a Redact/Refund request for a Soft Decline

  • Using the merchantTransactionId and customerId from Use Case 1 or 2, send a Refund-Payment POST request.
  • This transaction should be sent before the approved attempt has occurred. 

Use Case 7: Testing a GET Transaction List Request

  • After sending transactions to FlexPay in the earlier use cases, send a GET Transaction List request.
  • Use a date range in the parameters that covers the previous use cases.

Use Case 8: Testing GET Transaction List Pagination

Use Case 9: Testing hard decline response

  • Run this test if you are ingesting the result of the transaction response when first sending a decline to FlexPay.
  • Use the correct values for the FlexPay Sandbox gateway, or your chosen gateway's Sandbox endpoint (if available), to send a hard decline request.

Use Case 10: Testing an API validation error

  • Run this test if you are ingesting the result of the transaction response when first sending a decline to FlexPay.
  • Trigger an API validation error by sending an invalid request to FlexPay's API. For example: send an empty string ("") or NULL value for "customerId" AND "email".



 

 

D
Daniel is the author of this solution article.

Did you find it helpful? Yes No

Send feedback
Sorry we couldn't be helpful. Help us improve this article with your feedback.