OpenAPI: https://integrations.yoursafe.com/openapi/flowguard-api.json

# Flowguard API

## Yoursafe Flowguard

Yoursafe Flowguard is a cutting-edge payment integration solution designed for Verotel, CardBilling,
and Gaycharge. It provides an improved, modern alternative to redirect-based models, like FlexPay,
by allowing you to embed secure payment iframes directly into your order pages. This streamlines
the buyer's experience, removes redirects, thereby improving conversion rates without compromising
data security or PCI compliance.

## Key Benefits

- **No Redirects**: Flowguard boosts conversions by keeping buyers on your website without the need
for redirects
- **Fully PCI-DSS Compliant**: By using iframe components, Flowguard allows you to avoid handling
card-data. This significantly limits your PCI-DSS exposure
- **Highly Customizable**: The components are fully customizable, allowing you to create a fully
branded, seamless checkout experience
- **Reduced Fraud & Chargebacks**: As you are used to with our other integration methods, Flowguard
provides you with 3DS Support and strong fraud controls

## Core Components

Flowguard provides two main tools for integration: the Flowguard SDK and the Flowguard API. These
tools ensure that sensitive card data remains isolated from the merchant while offering a seamless
and fully customizable user experience.

### Flowguard SDK

This is the JavaScript-based toolkit that enables embedding iframes securely. The iframes are hosted
on flowguard.yoursafe.com, and remain isolated from your servers. It allows you to customize the
look and feel of the components to seamlessly integrate with your own page design.
See the [Flowguard SDK docs](https://flowguard.yoursafe.com/js/docs/) for more info.

### Flowguard API

This API allows you to initiate purchases and manage subscriptions. Transactions are processed in
the background. It also enables postback integrations, which provides you with any and all status updates.

## Need help?

For any questions or technical issues, feel free to contact our support team at
merchantsupport@verotel.com. We're here to assist you!

## Getting started

Welcome to the Yoursafe Flowguard API documentation.

Yoursafe Flowguard is designed to seamlessly integrate secure payment processing with full control, offering unparalleled control over your payment flow while ensuring top-tier security and compliance.

## Yoursafe Flowguard overview

Following overview provides a high-level understanding of how Yoursafe Flowguard works.

<img src="https://flowguard.yoursafe.com/js/docs/assets/flowguard_architecture.png" alt="Flowguard architecture" style="max-width: 600px">

## Security

All Yoursafe Flowguard API endpoints are secured with JWTs (Json Web Tokens), which ensures security of your data.

JWT has to consist of three parts: header, payload, and signature. We recommend [JWT Debugger](https://jwt.io/#debugger-io) if you need to debug your JWTs.

### JWT Header

JWT header has to contain the following fields:
| Field | Field value |
|:------|:------------|
| alg   | HS256       |
| typ   | JWT         |

### JWT Payload

Payload for JWT is a JSON object with different fields for each endpoint.

You can find the required fields in the specific endpoint documentation.

### JWT Signature

JWT has to be signed using the **signatureKey** that you will find in the **Control Center**. In the case JWT signature is not provided or is invalid, the API will return a `401 Unauthorized error`. An example of the code

### JWT Example
```json
// JWT Header
{{
    "alg": "HS256",
    "typ": "JWT"
}}
// JWT Body
{{
    "shopId": "65151",
    "priceAmount": "10.00",
    "priceCurrency": "USD",
    "successUrl": "https://merchant.com/success",
    "declineUrl": "https://merchant.com/decline",
    "postbackUrl": "https://merchant.com/postback",
    "email": "shoper@example.com"
}}

const signatureKey = "signatureKeyFromControlCenter";

console.log(await signJWT(header, payload, signatureKey));

// Output:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzaG9wSWQiOiI2NTE1MSIsInByaWNlQW1vd
W50IjoiMTAuMDAiLCJwcmljZUN1cnJlbmN5IjoiVVNEIiwic3VjY2Vzc1VybCI6Imh0dHBzOi8
vbWVyY2hhbnQuY29tL3N1Y2Nlc3MiLCJkZWNsaW5lVXJsIjoiaHR0cHM6Ly9tZXJjaGFudC5jb
20vZGVjbGluZSIsInBvc3RiYWNrVXJsIjoiaHR0cHM6Ly9tZXJjaGFudC5jb20vcG9zdGJhY2s
iLCJlbWFpbCI6InNob3BlckBleGFtcGxlLmNvbSJ9.z1aqZb0YR93Dw4_Gh6mVC4EWLxs_GDBJ
L_xEHHTeVdQ
```

An example of the signJWT function of the example above:

```
// Signing the JWT function - or use your own implementation
async function signJWT(header, payload, signatureKey) {
    const enc = new TextEncoder();
    const base64url = (obj) =>
        btoa(JSON.stringify(obj))
        .replace(/=/g, "")
        .replace(/\+/g, "-")
        .replace(/\//g, "_");
    const encodedHeader = base64url(header);
    const encodedPayload = base64url(payload);
    const data = `${encodedHeader}.${encodedPayload}`;
    const key = await crypto.subtle.importKey(
        "raw",
        enc.encode(signatureKey),
        { name: "HMAC", hash: "SHA-256" },
        false,
        ["sign"]
    );
    const sigBuffer = await crypto.subtle.sign("HMAC", key, enc.encode(data));
    const signature = btoa(String.fromCharCode(...new Uint8Array(sigBuffer)))
    .replace(/=/g, "")
    .replace(/\+/g, "-")
    .replace(/\//g, "_");

  return `${data}.${signature}`;
```

## Start Purchase

`POST /api/merchant/purchase/start`

API that allows you to integrate a single secure payment for your website.

Use this endpoint to initiate the order process for a single purchase. 

Response of this endpoint `sessionId` has to be passed to the
 [Yoursafe Flowguard SDK](https://flowguard.yoursafe.com/js/docs/) to start the payment process. 

This endpoint is secured by JWTs. You can find more information how to work with JWTs in the
[Security section](#section/Security).

### JWT Payload

JWT payload has to contain the following fields:

| Field         | Field type       | Note                                                   |
|:--------------|:-----------------|:-------------------------------------------------------|
| shopId        | number or string | Shop ID from ControlCenter.                            |
| priceAmount   | string           | In format NNN.NN                                       |
| priceCurrency | string           | One of: USD, EUR, GBP, AUD, CAD, CHF, DKK, NOK, SEK |
| successUrl    | string           | Max length 255 characters.                             |
| declineUrl    | string           | Max length 255 characters.                             |
| postbackUrl   | string           | Max length 255 characters.                             |
| email         | string           | Max length 100 characters.                             |
| referenceId   | string or null   | Optional. Max length 100 characters.                   |

### JWT Example

<style>
  pre {
    white-space: pre-wrap !important;
  }
  pre > code {
    color: rgb(160, 251, 170) !important;
  }
</style>

```
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzaG9wSWQiOiI2NTE1MSIsInByaWNlQW1vdW50IjoiMTAuMDAiLCJwcmljZUN1cnJlbmN5IjoiVVNEIiwic3VjY2Vzc1VybCI6Imh0dHBzOi8vbWVyY2hhbnQuY29tL3N1Y2Nlc3MiLCJkZWNsaW5lVXJsIjoiaHR0cHM6Ly9tZXJjaGFudC5jb20vZGVjbGluZSIsInBvc3RiYWNrVXJsIjoiaHR0cHM6Ly9tZXJjaGFudC5jb20vcG9zdGJhY2siLCJlbWFpbCI6InNob3BlckBleGFtcGxlLmNvbSJ9.J8LY9lYSI9HWAiZPjXKLZ7dXIMno9CBIRt5fk9M5gOM
```

### Request body (required)

application/jwt

- `Data` (string, required)

### Responses

#### 200

Successful Response

- `sessionId` (uuid, required)

#### 401

Unauthorized

- `errors` (string, required)

#### 422

Unprocessable Content

- `errors` (object, required)

#### 423

Locked

- `errors` (string, required)

```http
POST /api/merchant/purchase/start
```

```node
const url = new URL("/api/merchant/purchase/start");
const response = await fetch(url, { method: "POST" });
```

```python
from urllib.request import urlopen

response = urlopen("/api/merchant/purchase/start")
```

```php
// POST /api/merchant/purchase/start
$url = "/api/merchant/purchase/start";
```

```java
// POST /api/merchant/purchase/start
String url = "/api/merchant/purchase/start";
```

## Subscription

API that allows you to integrate subscription payments for your website.

## Cancel Subscription

`POST /api/merchant/subscription/cancel`

This endpoint is used to cancel a subscription. 

This endpoint is secured by JWTs. You can find more information how to work with JWTs in the
[Security section](#section/Security).

### JWT Payload

JWT payload has to contain the following fields:

| Field       | Field type       | Note                                                                        |
|:------------|:-----------------|:----------------------------------------------------------------------------|
| saleId      | number or string | Sale ID of subscription to cancel.                                          |
| shopId      | number or string | Shop ID from ControlCenter.                                                 |
| cancelledBy | string           | Optional, one of: merchant, buyer |

### JWT Example

<style>
  pre {
    white-space: pre-wrap !important;
  }
  pre > code {
    color: rgb(160, 251, 170) !important;
  }
</style>

```
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzaG9wSWQiOiI2NTE1MSIsInNhbGVJZCI6IjIwODAiLCJjYW5jZWxsZWRCeSI6Im1lcmNoYW50In0.gAbebyxDsecJrriAosWvtdi-SG_dt6MTVMC6NmOGriE
```

### Request body (required)

application/jwt

- `Data` (string, required)

### Responses

#### 200

Successful Response

#### 401

Unauthorized

- `errors` (string, required)

#### 422

Unprocessable Content

- `errors` (object, required)

```http
POST /api/merchant/subscription/cancel
```

```node
const url = new URL("/api/merchant/subscription/cancel");
const response = await fetch(url, { method: "POST" });
```

```python
from urllib.request import urlopen

response = urlopen("/api/merchant/subscription/cancel")
```

```php
// POST /api/merchant/subscription/cancel
$url = "/api/merchant/subscription/cancel";
```

```java
// POST /api/merchant/subscription/cancel
String url = "/api/merchant/subscription/cancel";
```

## Start Subscription

`POST /api/merchant/subscription/start`

Use this endpoint to initiate the subscription process.

Response of this endpoint `sessionId` has to be passed to the
[Yoursafe Flowguard SDK](https://flowguard.yoursafe.com/js/docs/) to start the payment process.

This endpoint is secured by JWTs. You can find more information how to work with JWTs in the
[Security section](#section/Security).

### JWT Payload

JWT payload has to contain the following fields:

| Field            | Field type       | Note                                                           |
|:-----------------|:-----------------|:---------------------------------------------------------------|
| shopId           | number or string | Shop ID from ControlCenter.                                    |
| priceAmount      | string           | In format NNN.NN                                               |
| priceCurrency    | string           | One of: USD, EUR, GBP, AUD, CAD, CHF, DKK, NOK, SEK         |
| successUrl       | string           | Max length 255 characters.                                     |
| declineUrl       | string           | Max length 255 characters.                                     |
| postbackUrl      | string           | Max length 255 characters.                                     |
| email            | string           | Max length 100 characters.                                     |
| subscriptionType | string           | One of: recurring, one-time |
| period           | string           | In ISO 8601 period format (e.g. P30D, P1M, P1Y)                |
| referenceId      | string or null   | Optional. Max length 100 characters.                           |
| trialAmount      | string or null   | Optional. In format NNN.NN                                     |
| trialPeriod      | string or null   | Optional. In ISO 8601 period format (e.g. P30D, P1M, P1Y)      |

### Period format
Period consists of 3 parts (P, number, unit). Units can be: D - day, M - month, Y - year.
For example:
- P30D - 30 days
- P1M - 1 month
- P1Y - 1 year

#### Minimum and maximum period restrictions
- for one-time subscription minimum period length is 2 days, maximum period length is 180 days
- for recurring subscription minimum period length is 7 days, maximum period length is 180 days
- maximum period can be prolonged up to 730 days if merchant has long subscriptions enabled

#### Minimum and maximum trialPeriod restrictions
- minimum trialPeriod length is 2 days, maximum trialPeriod length is 180 days
- maximum trialPeriod can be prolonged up to 730 days if merchant has long subscriptions enabled

### JWT Example

<style>
  pre {
    white-space: pre-wrap !important;
  }
  pre > code {
    color: rgb(160, 251, 170) !important;
  }
</style>

```
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzaG9wSWQiOiI2NTE1MSIsInByaWNlQW1vdW50IjoiMTAuMDAiLCJwcmljZUN1cnJlbmN5IjoiVVNEIiwic3VjY2Vzc1VybCI6Imh0dHBzOi8vbWVyY2hhbnQuY29tL3N1Y2Nlc3MiLCJkZWNsaW5lVXJsIjoiaHR0cHM6Ly9tZXJjaGFudC5jb20vZGVjbGluZSIsInBvc3RiYWNrVXJsIjoiaHR0cHM6Ly9tZXJjaGFudC5jb20vcG9zdGJhY2siLCJlbWFpbCI6InNob3BlckBleGFtcGxlLmNvbSIsInN1YnNjcmlwdGlvblR5cGUiOiJyZWN1cnJpbmciLCJwZXJpb2QiOiJQMU0iLCJ0cmlhbEFtb3VudCI6IjUuMDAiLCJ0cmlhbFBlcmlvZCI6IlAzRCJ9.EwpofyMOWGqqmk4RQU7DgQHWCxl32GQLckrNOnHBSy4
```

### Request body (required)

application/jwt

- `Data` (string, required)

### Responses

#### 200

Successful Response

- `sessionId` (uuid, required)

#### 401

Unauthorized

- `errors` (string, required)

#### 422

Unprocessable Content

- `errors` (object, required)

#### 423

Locked

- `errors` (string, required)

```http
POST /api/merchant/subscription/start
```

```node
const url = new URL("/api/merchant/subscription/start");
const response = await fetch(url, { method: "POST" });
```

```python
from urllib.request import urlopen

response = urlopen("/api/merchant/subscription/start")
```

```php
// POST /api/merchant/subscription/start
$url = "/api/merchant/subscription/start";
```

```java
// POST /api/merchant/subscription/start
String url = "/api/merchant/subscription/start";
```

## Postbacks

This part of documentation outlines the event types that occur during the payment process and the mechanism for
 receiving notifications via postbacks.

### Postback URL Configuration
When invoking the `purchase/start` or `subscription/start` endpoints, you are required to provide a `postbackUrl`.
 This URL will be used to send notifications of relevant events.

### Postback Format
The postback will be sent as a JWT (JSON Web Token) token, which will be signed using your provided signature key.
 Upon receiving the postback, your system must respond with an HTTP status code of 200 OK in 30 seconds.

### Retry Policy
In the event that your system does not respond with a 200 OK status code, the API will automatically retry sending
 the postback up to three (3) times.

### Postback Content
The JWT token included in the postback will contain a field named postbackType. This field indicates the type of event
 that has occurred. Refer to the sections below for detailed information on the data structure for each event type that
 may be sent via postback.

## Purchase approved

Postback sent when a purchase is successfully completed by a buyer. <br />
We will automatically refund the payment if the postback is not received (if your system does not respond with 200 OK
HTTP status) after all retries.

| Field         | Field type       | Note                                                   |
|:--------------|:-----------------|:-------------------------------------------------------|
| postbackType  | string           | `approved`                                             |
| orderType     | string           | `purchase`                                             |
| saleId        | number or string |                                                        |
| transactionId | number or string |                                                        |
| shopId        | number or string | Shop ID from ControlCenter.                            |
| priceAmount   | string           | In format `NNN.NN`                                     |
| priceCurrency | string           | One of: USD, EUR, GBP, AUD, CAD, CHF, DKK, NOK, SEK |
| referenceId   | string or null   | Optional                                               |

## Purchase refund

Both chargeback and credit postbacks represent refund transactions of purchase.
They differ in terms of the initiator of the refund.

| Field         | Field type       | Note                                                   |
|:--------------|:-----------------|:-------------------------------------------------------|
| postbackType  | string           | `chargeback` , `credit`                                |
| orderType     | string           | `purchase`                                             |
| saleId        | number or string |                                                        |
| transactionId | number or string |                                                        |
| shopId        | number or string | Shop ID from ControlCenter.                            |
| parentId      | number or string | Id of transaction that is being refunded               |
| priceAmount   | string           | In format `NNN.NN`                                     |
| priceCurrency | string           | One of: USD, EUR, GBP, AUD, CAD, CHF, DKK, NOK, SEK |
| referenceId   | string or null   | Optional                                               |

## Subscription approved

Postback sent when a subscription is successfully completed by a buyer. <br />
We will automatically refund the payment if the postback is not received (if your system does not respond with 200 OK
HTTP status) after all retries.

| Field             | Field type       | Note                                                                     |
|:------------------|:-----------------|:-------------------------------------------------------------------------|
| postbackType      | string           | `approved`                                                               |
| orderType         | string           | `subscription`                                                           |
| saleId            | number or string |                                                                          |
| transactionId     | number or string |                                                                          |
| shopId            | number or string | Shop ID from ControlCenter.                                              |
| priceAmount       | string           | In format `NNN.NN`                                                       |
| priceCurrency     | string           | One of: USD, EUR, GBP, AUD, CAD, CHF, DKK, NOK, SEK                   |
| subscriptionType  | string           | `recurring` , `one-time`                                                 |
| subscriptionPhase | string           | `normal` , `trial`                                                       |
| nextChargeOn      | string or null   | Optional. In format `YYYY-MM-DD`. Present for recurring subscriptionType |
| expiresOn         | string or null   | Optional. In format `YYYY-MM-DD`. Present for one-time subscriptionType. |
| referenceId       | string or null   | Optional                                                                 |

## Subscription refund

Both chargeback and credit postbacks represent refund transactions of subscription.
They differ in terms of the initiator of the refund.

| Field             | Field type       | Note                                                   |
|:------------------|:-----------------|:-------------------------------------------------------|
| postbackType      | string           | `chargeback` , `credit`                                |
| orderType         | string           | `subscription`                                         |
| saleId            | number or string |                                                        |
| transactionId     | number or string |                                                        |
| shopId            | number or string | Shop ID from ControlCenter.                            |
| parentId          | number or string | Id of transaction that is being refunded               |
| priceAmount       | string           | In format `NNN.NN`                                     |
| priceCurrency     | string           | One of: USD, EUR, GBP, AUD, CAD, CHF, DKK, NOK, SEK |
| subscriptionType  | string           | `recurring` , `one-time`                               |
| subscriptionPhase | string           | `terminated`                                           |
| referenceId       | string or null   | Optional                                               |

## Subscription rebill

Postback sent when each recurring subscription payment is successfully processed. For example, if a subscription period is set do `P1M`, a rebill postback will be sent each month.

| Field             | Field type       | Note                                                   |
|:------------------|:-----------------|:-------------------------------------------------------|
| postbackType      | string           | `rebill`                                               |
| orderType         | string           | `subscription`                                         |
| saleId            | number or string |                                                        |
| transactionId     | number or string |                                                        |
| shopId            | number or string | Shop ID from ControlCenter.                            |
| priceAmount       | string           | In format `NNN.NN`                                     |
| priceCurrency     | string           | One of: USD, EUR, GBP, AUD, CAD, CHF, DKK, NOK, SEK |
| subscriptionType  | string           | `recurring`                                            |
| subscriptionPhase | string           | `normal`                                               |
| nextChargeOn      | string           | In format `YYYY-MM-DD`.                                |
| referenceId       | string or null   | Optional                                               |

## Subscription expiration

This postback will be sent, after the last subscription payment.

| Field            | Field type       | Note                        |
|:-----------------|:-----------------|:----------------------------|
| postbackType     | string           | `expiry`                    |
| orderType        | string           | `subscription`              |
| saleId           | number or string |                             |
| shopId           | number or string | Shop ID from ControlCenter. |
| subscriptionType | string           | `recurring` , `one-time`    |
| referenceId      | string or null   | Optional                    |

## Subscription cancel

This postback will be sent, after the subscription is cancelled.

| Field             | Field type       | Note                                       |
|:------------------|:-----------------|:-------------------------------------------|
| postbackType      | string           | `cancel`                                   |
| orderType         | string           | `subscription`                             |
| saleId            | number or string |                                            |
| shopId            | number or string | Shop ID from ControlCenter.                |
| subscriptionType  | string           | `recurring`                                |
| subscriptionPhase | string           | `normal` , `trial`                         |
| cancelledBy       | string           | `user` , `support` , `merchant` , `system` |
| expiresOn         | string or null   | Optional. In format `YYYY-MM-DD`.          |
| referenceId       | string or null   | Optional                                   |

## Subscription uncancel

This postback will be sent, after the subscription is uncancelled.

| Field             | Field type       | Note                                                                       |
|:------------------|:-----------------|:---------------------------------------------------------------------------|
| postbackType      | string           | `uncancel`                                                                 |
| orderType         | string           | `subscription`                                                             |
| saleId            | number or string |                                                                            |
| shopId            | number or string | Shop ID from ControlCenter.                                                |
| subscriptionType  | string           | `recurring`                                                                |
| subscriptionPhase | string           | `normal` , `trial`                                                         |
| uncancelledBy     | string           | `support`                                                                  |
| nextChargeOn      | string or null   | Optional. In format `YYYY-MM-DD`. Present if subscription is still active. |
| referenceId       | string or null   | Optional                                                                   |

## Subscription extended

Postback sent when subscription is extended.

| Field             | Field type       | Note                                                                     |
|:------------------|:-----------------|:-------------------------------------------------------------------------|
| postbackType      | string           | `extend`                                                                 |
| orderType         | string           | `subscription`                                                           |
| saleId            | number or string |                                                                          |
| shopId            | number or string | Shop ID from ControlCenter.                                              |
| subscriptionType  | string           | `recurring` , `one-time`                                                 |
| subscriptionPhase | string           | `normal` , `trial`                                                       |
| nextChargeOn      | string or null   | Optional. In format `YYYY-MM-DD`. Present for recurring subscriptionType |
| expiresOn         | string or null   | Optional. In format `YYYY-MM-DD`. Present for one-time subscriptionType. |
| referenceId       | string or null   | Optional                                                                 |
