# Payment flow

## Payments

System overview of a succesful payment.

<figure><img src="/files/0gjeMTyfAcbxuC3MjtNR" alt=""><figcaption><p>Create a payment</p></figcaption></figure>

### **Step 1**

To initiate a payment, create a payment intent from your POS system towards the process\_payment\_intent endpoint of the Vibrant API. In return you get a unique id of the payment intent object created in the system.

A terminal Id must be supplied in the request in order to select a terminal device.

A payment intent cannot be updated. To change the amount a new payment intent should be created.

{% hint style="success" %}
*Idempotency*

[It is possible to provide a unique idempotency key with your request to avoid creating the same request multiple times](#user-content-fn-1)[^1][ by mistake.](#user-content-fn-1)[^1]
{% endhint %}

### **Step 2**

The customer tabs their card against the terminal to initiate the transaction.

The payment intent will change status to succeeded, when/if the transaction is approved.

{% hint style="info" %}
During this step the terminal object will indicate that the terminal is busy, and it is not possible to send other payments/refunds to this terminal at this point.

It is however possible to send a cancel action to the terminal to abort the payment being processed. See more details under [Terminal actions](/vibrant/vibrant-sandbox/terminal-actions.md).
{% endhint %}

### **Step 3**

Update your POS system with status of the payment intent. Either subscribe to a webhook to get events pushed, or pull the data using the id of the payment intent.

## Payment Intent states

Here is an overview of the state changes that a payment intent can overcome.

<figure><img src="/files/CMwwUxs7jCJaRpwahh2Q" alt=""><figcaption></figcaption></figure>

`requires_payment_method`

This state is used when the payment intent is initially created.&#x20;

If the payment fails during `processing` the state can return to `requires_payment_method`. For instance if the credit card is declined. The payment intent can be sent for processing on a terminal again.

`requires_action`

The payment intent will be in this state if the payment awaits the customer to enter PIN code.

`processing`

This state is used when the payment is being processed. It can no longer be cancelled.

{% hint style="info" %}
At this point a Charge object is also created. The charge will hold card details, failure message, receipt id, refund information and more.

More charges can be created for the same payment intent, if that payment fails and is tried again.
{% endhint %}

`succeeded`

The payment has succeeded.

`cancelled`

The payment has been cancelled. Please create a new Payment Intent to start another payment.

## Refunds

The flow for refunds is exactly the same as for payment intents.

To process a refund, you must provide the id of a successful Payment Intent. It is only possible to refund the entire amount - no partial refunds.

A payment intent can only be refunded once.

[^1]:


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.vibrant.io/vibrant/vibrant-sandbox/payment-flow.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
