---
updatedAt: 2025-09-24T00:50:27.000Z
agentTools:
  projectIndex: https://docs.skipify.com/llms.txt
---

# Recurring Transactions

Learn how to implement recurring, or merchant initiated transactions

> 📘 Prerequisite
>
> Scope your Commerce Identity Checkout implementation shape before proceeding with implementing recurring transactions

# Overview

Skipify supports various types of recurring transactions or merchant initiated transactions (MIT)s across various implementation shapes.

Implementing recurring transactions comprises of 2 key components:

1. the [initial payment](https://docs.skipify.com/docs/merchant-initiated-transactions#initial-payment-cit) with customer in-session (CIT)
2. subsequent, recurring [merchant initiated transactions (MITs)](https://docs.skipify.com/docs/merchant-initiated-transactions#merchant-initiated-transactions-mit) that are scheduled by your subscription and/or billing engine. These MITs are triggered by the merchant, without any specific customer action.

> 🚧 Maintain subscription and/or billing engine logic on your end, or with a third party partner.

# Tech Overview

> 📘 The below recurring transactions implementation is relevant for the most common, default payment submission scope: Skipify authorizing on your behalf

<Image align="center" width="500px" src="https://files.readme.io/d0ccbf7394eeb0ea877fe7680a7a2c594f3aea613a00f69bb6ee0a838b23fd98-image.png" />

## Initial Payment (CIT)

Define and submit the initial payment by simply adding the `enableRecurring: true` flag to the root object of your current implementation shape's standard request payload.

Sending the `enableRecurring: true` flag in the current request payload results in the below:

* Checkout SDK, Paylinks UI -- triggers a [consent banner](https://docs.skipify.com/docs/merchant-initiated-transactions#consent-banner) to be displayed
* submits the initial transaction to be processed as a CIT
* ensures that the transaction and associated payment method is eligible for future MITs
* if the initial payment (CIT) is processed successfully, returns a `recurringMethodId` in the root object alongside the standard response payload parameters.

Store the `recurringMethodId` as it will be used to submit the future recurring MIT requests.

Refer to the below table for initial payment specifics based on your implementation shape:

<Table align={["left","left","left","left"]}>
  <thead>
    <tr>
      <th>
        Eligible Implementation Shape
      </th>

      <th>
        Submit the initial payment by adding

        `enableRecurring:true`

        to this root object
      </th>

      <th>
        auto display customer consent banner?
      </th>

      <th>
        `recurringMethodId`

         returned via this root object
      </th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>
        [Embedded Components SDK](https://docs.skipify.com/docs/skipify-embedded-components) \*
      </td>

      <td>
        [`POST /payments`](https://docs.skipify.com/docs/skipify-embedded-components#skipify-authorizes-on-your-behalf)\
        *\*where payment submission scope = (default flow) Skipify authorizes on your behalf*
      </td>

      <td>
        n/a, handle on your UI
      </td>

      <td>
        `POST /payments` response
      </td>
    </tr>

    <tr>
      <td>
        [Checkout SDK](https://docs.skipify.com/docs/skipify-sdk)
      </td>

      <td>
        [`ORDER_RESOLVE`](https://docs.skipify.com/docs/skipify-sdk#order_resolve-callback-event)
      </td>

      <td>
        yes
      </td>

      <td>
        [`order_payment_succeeded` ](https://docs.skipify.com/docs/webhooks#event-types)webhook
      </td>
    </tr>

    <tr>
      <td>
        [Paylinks API](https://docs.skipify.com/docs/paylink-endpoints)
      </td>

      <td>
        [`POST /paylinks.skipify.com`](https://docs.skipify.com/docs/creating-paylinks)
      </td>

      <td>
        yes
      </td>

      <td>
        [`order_payment_succeeded` ](https://docs.skipify.com/docs/webhooks#event-types)webhook
      </td>
    </tr>
  </tbody>
</Table>

### Consent Banner

Banner text: "By confirming your payment, you allow \[merchant\_name] to store your payment method for future usage in accordance with their terms”

<Image alt="recurring transactions consent banner: (L) Checkout SDK, (R) Paylinks" align="center" width="450px" src="https://files.readme.io/38fe210d3b334b9a21da0fa66f9e5631679c09dddc114db7a284583121f25327-image.png">
  recurring transactions consent banner: (L) Checkout SDK, (R) Paylinks
</Image>

## Merchant Initiated Transactions (MIT)

Once your billing engine signals that it is time to trigger a scheduled charge, call `POST /payments` referencing the previously stored `recurringMethodId` to submit the MIT.

The transaction processing result of the MIT is returned synchronously in the `POST /payments` response.

200 HTTP response code is returned alongside a payload when the MIT has been successfully submitted for payments processing. Refer to the `status` and `pspRawResponse` parameters for the actual psp transaction processing result.

```json MIT - request
POST /payments
{
  "recurringMethodId": "73c335b2-0dad-4e4a-b10b-950614f80953", // previously stored id referencing the initial CIT and its payment method
  "amount": 5000, // recurring transaction charge amount
  "merchantReference": "merchantUniqueIdentifier" // your unique order or cart reference
}
```
```json MIT - response 200
POST /payments response
// MIT has been successfully submitted for payments processing

{
  "transactionId": "73c335b2-0dad-4e4a-b10b-950614f80953",
  "pspTransactionId": "dE3Hnj7c_SD9",
  "status": "Authorized", // MIT was authorized successfully, else "Captured", "Failed"
  "amount": 5000,
  "initialAmount": 5000,
  "pspRawResponse": "FWWp", // wrapper containing the actual response from psp
  "completedAt": "2025-07-21T17:32:28Z",
  "lastFour": "0005",
  "networkType": "visa",
  "isPartial": false,
  "isMerchantInitiated": true // flags this as a MIT
}
```
```json MIT - error
POST /payments response
// MIT request was not able to be processed, i.e.: not eligible

{{confirm payload}}
```

Repeat this step as relevant based on your billing engine's schedule.

## Recurring Transactions for specific payment submission scope

> 🚧 Refer to this section only if you have been approved for this payment submission scope: retrieve payment credentials to authorize outside of Skipify

The recurring transactions implementation is different for this payment submission scope due to:

* you directly authorize and/or process the payments with the psp using the retrieved payment credentials stored on your servers
* you must notify Skipify of the transaction processing result whenever the payment credentials have been utilized

The e2e recurring transactions implementation flow is described below.

<Callout icon="📓" theme="default">
  ### The delta for implementing recurring transactions compared to your existing integration is simply the net new`isRecurring` flag in the existing `POST /payments/externalresponse` request
</Callout>

Utilize your existing implementation to **retrieve the payment credentials** as normal:

* request payment credentials retrieval for a payment method (`paymentId`)  via `POST /payments/credentials`
* if eligible, payment credentials are returned via the `PAYMENT_CREDENTIALS` webhook.

Submit the **initial payment** using the retrieved payment credentials using your direct payments processing integration. Ensure that the transaction is flagged as a recurring transaction, and you have displayed the relevant consent to your customers.

* Call `POST /payments/external-response` to notify Skipify of the transaction processing result

```json POST /payments/external-response - request
// Send the payments processing result to Skipify 
{
  "paymentID": "73c335b2-0dad-4e4a-b10b-950614f80953", // identifer of the retrieved payment credentials
  "pspRawResponse": "string", // wrapper encapsulating the raw psp response payload
  "amount": 5000,
  "pspHostName": "Stripe",
	"merchantReference": "merchantUniqueReference", // Your unique order or cart id
  "currencyCode": "USD",
  "isRecurring": true // add this flag to signal that it was a MIT
}
```
```Text POST /payments/external-response - response
Skipify sends ACK
```

Your billing engine indicates that it's time for the **recurring MIT** to be processed. Utilize the stored payment credentials associated to the initial payment to submit the transactions directly yourselves. Ensure the transcation is flagged as MIT.

* Call `POST /payments/externalresponse` to notify Skipify of the transaction processing result as shown in above example.

Repeat as the above recurring MIT steps as relevant for the future recurring MITs.