# Payment Execution Service



import Image from 'next/image';

The payment execution service processes invoice payments through payment providers such as Stripe and Braintree. Payments can be executed automatically using the [Autopay plugin](/configuration/plugins/autopay-and-payment-execution) or manually using the [Payments API](/api/billing/payments).

<Callout type="warn">
  The payment execution service currently supports [Braintree ](https://www.paypal.com/us/braintree) and [Stripe ](https://stripe.com). Contact your Socotra account representative to request support for additional payment providers.
</Callout>

Payment Lifecycle [#payment-lifecycle]

Payments typically begin in the `draft` state before moving to the `validated` state. However, the Autopay plugin can be configured to create payments that begin in one of the following states: `draft`, `validated`, `requested`, or `posted`.

Once a payment is in the `requested` state, the payment execution service will attempt to execute the payment through a payment provider and [financial instrument](/features/billing/payments#financial-instrument) associated with the [account](/features/accounts) to be charged, and the payment will move to the `executing` state.

If the payment provider successfully executes the payment request, the payment will be moved to the `posted` state, and payments will be distributed according to the targets specified in the payment request. An <ApiLink name="ExternalCashTransactionResponse">external cash transaction</ApiLink> record will also be generated for the payment.

If the payment provider fails to execute the payment request, and a [retry plan](#retry-plan) has been defined, the retry plan will be executed, and the payment will revert to the `requested` state. If the retry plan fails or a retry plan has not been defined, the payment will move to the `failed` state.

Refer to the diagram below for more information on the payment lifecycle.

<Image src="/images/payments/payment-state-flow.png" alt="payment state flow" width={800} height={356} unoptimized />

Setup [#setup]

Follow the instructions below to begin processing payments through the payment execution service.

Create a Default Financial Instrument [#create-a-default-financial-instrument]

The payment execution service requires a default [financial instrument](/features/billing/payments#financial-instrument) associated with the [account](/features/accounts) to be charged.

First, call the <ApiLink name="createFinancialInstrument">Create a Financial Instrument</ApiLink> API endpoint.

Here's an example request:

```json
{
	"externalIdentifier": "example_identifier",
	"institutionName": "Example Bank",
	"instrumentType": "checking",
	"defaultTransactionMethod": "ach",
	"externalAccountNumber": "1234567890",
	"accountLocator": "01JAB5N9X2M7QFZ4YWT8K3HV6R",
	"nickname": "Example Nickname"
}
```

Then call the <ApiLink name="setFinancialInstrumentAsDefault">Set the Default Financial Instrument for a Tenant</ApiLink> API endpoint using the financial instrument that was created in the previous step.

Here's an example URL for this endpoint, since the request body will be empty:

```
POST billing/01JAB5N9X2M7QFZ4YWT8K3HV6R/financialInstruments/01HZX9Y4P6D2W8TBK3F7QJM9RV/setAsDefault?value=true
```

Before payments are posted, they may be in `requested` state. This indicates that the payment should be processed with a transaction with an external financial institution and then distributed according to the payment request's targets. Payments in `requested` state are typically called *Payment Requests*.

Payments can be created in `requested` state either using the [Autopay](/features/billing/autopay) feature, or directly using the <ApiLink name="createPayment" /> API. They will be processed by the payment execution service in the same way.

Add a Payment Provider Configuration [#add-a-payment-provider-configuration]

Call the <ApiLink name="addPaymentProviderConfiguration">Add Payment Provider Configuration</ApiLink> API endpoint. The request details differ based on the payment provider the policyholder is using to make payments.

Braintree [#braintree]

For Braintree, the `paymentServiceProvider`, `merchantId`, `publicKey`, and `privateKey` fields are required. The `paymentServiceProvider` value should be set to "braintreeSandbox" for sandbox environments and "braintree" for production environments.

The `merchantId`, `publicKey`, and `privateKey` values can be found by navigating to the account icon in the upper right corner of the [Braintree dashboard ](https://sandbox.braintreegateway.com), clicking *My User*, then clicking *View Authorizations* under the *API Keys, Tokenization Keys, Encryption Keys* section.

Here's an example request for the <ApiLink name="addPaymentProviderConfiguration">Add Payment Provider Configuration</ApiLink> API endpoint using a Braintree sandbox account:

```json
{
	"paymentServiceProvider": "braintreeSandbox",
	"merchantId": "hfa37hqzhf",
	"publicKey": "3c8zEmhfshd",
	"privateKey": "ZzFe7v7vcd"
}
```

Stripe [#stripe]

For Stripe, the `paymentServiceProvider` and `secretKey` fields are required. The `paymentServiceProvider` value should be set to "stripeTest" for sandbox environments and "stripe" for production environments.

The `secretKey` value can be found by navigating to the *Developer* tab in the lower left corner of the [Stripe dashboard ](https://dashboard.stripe.com) and clicking *API keys*.

Socotra will automatically create a webhook configuration in Stripe after validating payment provider credentials. To view webhook configurations in Stripe, navigate to the *Developer* tab, then click *Webhooks*.

<Callout type="warn">
  Do not edit or delete webhook configurations in Stripe.
</Callout>

Here's an example request for the <ApiLink name="addPaymentProviderConfiguration">Add Payment Provider Configuration</ApiLink> API endpoint using a Stripe sandbox account:

```json
{
	"paymentServiceProvider": "stripeTest",
	"secretKey": "3c8zEmhfshd"
}
```

Add Payment Execution Configuration for Financial Instrument [#add-payment-execution-configuration-for-financial-instrument]

Call the <ApiLink name="addPaymentExecutionConfigurationForFinancialInstrument">Add Payment Execution Configuration for Financial Instrument</ApiLink> API endpoint using the `paymentProviderLocator` from the payment provider configuration that was created in the previous step.
Payment execution configurations contain payment method tokens required to execute payment requests on behalf of policyholders.

The `offlinePaymentToken` refers to the *Payment Method Token* in Braintree and the *Payment Method ID* in Stripe.

The *Payment Method Token* can be found in Braintree by navigating to the *Transactions* tab, searching for a transaction, clicking the transaction ID, and then locating the *Payment Method Token* field under the *Payment Information* section.

The *Payment Method ID* can be found in Stripe by navigating to the *Transactions* tab, clicking a transaction, then looking for the *ID* field under the *Payment Method* section.

Here's an example request for the <ApiLink name="addPaymentExecutionConfigurationForFinancialInstrument">Add Payment Execution Configuration for Financial Instrument</ApiLink> API endpoint:

```json
{
	"paymentProviderLocator": "01M4QZ7X2Y8P5K9B0R3F6T1VJS",
	"offlinePaymentToken": "j2fd9fhHyeNHe32"
}
```

<Callout>
  The details of the payment providers and tokens are managed in a separate service in order to facilitate [PCI-Compliance ](https://listings.pcisecuritystandards.org/assessors_and_solutions/vpa_agreement). Please review Socotra's [PCI Compliance Statement](/features/security/pci-compliance-statement) for more information.
</Callout>

<span id="retry-plan" />

Retry Plans [#retry-plans]

Retry plans contain the following properties:

* `attempts`: The maximum number of attempts to execute a payment request
* `hoursBetweenAttempts`: How long to wait between attempts

The retry plan can be set in any of the following places, and the system will go through this list in order until it finds a plan:

* The payment
* The <ApiLink name="FinancialInstrumentResponse">financial instrument</ApiLink>
* The account
* The default retry plan defined in the tenant <ApiLink name="ConfigurationRef">configuration</ApiLink>

While the payment is awaiting a retry, you can manually override the process using the following API endpoints:

* Use the <ApiLink name="executePayment" /> API endpoint to execute a payment manually
* Use the <ApiLink name="postPayment" /> API endpoint to update the payment state to `posted`
* Use the <ApiLink name="failPayment" /> API endpoint to indicate that the payment cannot be processed
* Use the <ApiLink name="cancelPayment" /> API endpoint to indicate that the payment is no longer needed
* Use the <ApiLink name="updatePayment" /> API endpoint to manually change the `nextRequestTime` to retry sooner or later than scheduled

<Callout>
  The <ApiLink name="executePayment" /> API endpoint can also be used to move a payment from the `requested` state to the `validated` state without waiting for the `autopayTime`.
</Callout>

Refer to the diagram below for more information on the retry process.

<Image src="/images/autopay/autopay-payment-request-flow.png" alt="autopay payment request flow" width={800} height={345} unoptimized />

<span id="payment-execution-post-processing-plugin" />

Post-Execution Plugin [#post-execution-plugin]

After the payment execution is attempted, the Payment Post-Execution Plugin is called with the following fields:

* The `paymentLocator`
* The `financialInstrumentLocator`
* The payment `amount`
* The payment `state`
* An `externalTransactionId`, if one exists
* The payment `currency`
* Extension `data` for the payment

The plugin returns a response with the following fields:

* The `nextRequestTime`, if you wish to override the default `hoursBetweenAttempts` in the retry plan
* An updated payment `amount`
* An updated `state` for the payment (`posted`, `cancelled`, or `failed`)
* A `note`

The Post-Execution plugin will not be called under certain circumstances, such as when the payment provider system is unavailable or if credentials are outdated. Plugin execution will fail if the payment `state` field is updated to either of the following values: `executing` or `reversed`.

If the Post-Execution plugin returns a `nextRequestTime`, even if the number of retry attempts has already exceeded the number of retry attempts specified in the retry plan, retry attempts will continue.

<Callout type="warn">
  If the Post-Execution Plugin fails for a payment, the payment will be moved to the `failed` state, even if the payment provider successfully executed the payment. The information from the provider's response will be available in the payment history, including failure details in the `note`. If a payment provider fails to execute a payment, you should post the payment manually and resolve the cause of the failure to prevent future issues.
</Callout>

Execution Log [#execution-log]

The history of execution attempts is maintained in the `executionLog` property for each <ApiLink name="PaymentResponse">payment</ApiLink>.

Here's an example of a log entry:

<ApiSchema name="PaymentRequestExecutionLogItem" />

See Also [#see-also]

* [Payments](/features/billing/payments)
* [Autopay](/features/billing/autopay)
* [Payments API](/api/billing/payments)
* [Payment Execution API](/api/billing/payment-execution)
* [Payment Execution Plugin](/configuration/plugins/autopay-and-payment-execution)
* [Financial Instruments and External Cash Transactions API](/api/billing/financial-instruments)


## API Reference

PaymentRequestExecutionLogItem
Properties:
  paymentRequestLocator (ulid, required)
  paymentRequestState (Enum pending | completed | failed | error, required)
  requestTime (datetime)
  transactionId (string)
  note (string)
  data (map<string, object>, required)