# Payments API

API endpoints for processing payments in the Dime payment system.

**Version:** 1.0.0

## Servers

- **Production:** `https://api.dimepay.app/dapi/v1`
- **Sandbox:** `https://sandbox.api.dimepay.app/dapi/v1`


## Authentication

All endpoints require the `client_key` header.

```http
client_key: abcd1234
```

## Endpoints

### 1) Create a Hosted Payment Page

**POST** `/payments/hosted-page`

Creates a hosted checkout page and returns an `order_url` for redirect.

#### Headers

- `client_key` (string, required)


#### Request Body

| Field | Type | Required | Description |
|  --- | --- | --- | --- |
| `lang` | string | Yes | Language for the flow. Example: `en` |
| `data` | string (JWT) | Yes | A **signed JWT** with the fields below. |


**Fields to include in the JWT payload:**

- `webhookUrl`: Your backend URL to receive payment events.
- `redirectUrl`: URL to redirect after successful payment.
- `checkoutUrl`: URL to send the user back to checkout.
- `currency`, `id`, `subtotal`, `total`, `email`, `tax`, `ipAddress`, `fulfilled`, `orderComments`, `discount`, `items[]`, `billingPerson`, `shippingPerson`, `referenceTransactionId`, `taxes[]`, `tokenize`.


#### Example Unsigned Payload

```json
{
  "webhookUrl": "https://webhookurl",
  "redirectUrl": "https://redirectUrl",
  "checkoutUrl": "https://checkoutUrl",
  "tokenize": false,
  "currency": "USD",
  "id": "XJ12H",
  "subtotal": 1076.64,
  "total": 2014.97,
  "email": "mscott@gmail.com",
  "tax": 488.48,
  "ipAddress": "195.151.247.241",
  "fulfilled": true,
  "orderComments": "555",
  "discount": 4,
  "items": [
    {
      "id": "xxxx-xxxx-xxxx-xxxx",
      "price": 1060,
      "sku": "ABCA-IAC",
      "quantity": 1,
      "shortDescription": "",
      "name": "iMac",
      "imageUrl": "https://example.com/images/xxxxxx.jpg",
      "selectedOptions": [
        { "name": "Color", "value": "red", "type": "CHOICE" }
      ]
    }
  ],
  "billingPerson": {
    "name": "Michael Scott",
    "email": "",
    "companyName": "",
    "street": "555 Lackawanna Ave",
    "city": "Scranton",
    "countryCode": "US",
    "countryName": "United States",
    "postalCode": "18508",
    "stateOrProvinceCode": "PA",
    "stateOrProvinceName": "Pennsylvania",
    "phone": ""
  },
  "shippingPerson": {
    "name": "Michael Scott",
    "email": "",
    "companyName": "",
    "street": "555 Lackawanna Ave",
    "city": "Scranton",
    "countryCode": "US",
    "countryName": "United States",
    "postalCode": "18508",
    "stateOrProvinceCode": "PA",
    "stateOrProvinceName": "Pennsylvania",
    "phone": ""
  },
  "referenceTransactionId": "transaction_65306446",
  "taxes": [ { "name": "New Tax 2", "value": 12, "total": 57.1 } ]
}
```

#### Example: Signing the Payload

```javascript
const jwt = require('jsonwebtoken');
const payload = { /* fields above */ };
const signedData = jwt.sign(payload, 'your_secret_key');
```

#### Final Request Payload

```json
{ "lang": "en", "data": "<signed_jwt_token>" }
```

#### Response (201)

```json
{ "order_url": "https://sandbox.dimepay.app/e-order/abcd1234" }
```

### 2) Authorize a Payment

**POST** `/payments/auth`

Places a hold on funds (no capture yet).

#### Headers

- `client_key` (string, required)


#### Request Body (PaymentInputWithParams)

| Field | Type | Required | Description |
|  --- | --- | --- | --- |
| `lang` | string | Yes | Example: `en` |
| `data` | string (JWT) | Yes | A **signed JWT** with payment details and `paymentParams`. |


**Fields to include in the JWT payload:**

- Standard order fields: `currency`, `id`, `subtotal`, `total`, `email`, `tax`, `ipAddress`, `fulfilled`, `orderComments`, `discount`, `items[]`, `billingPerson`, `shippingPerson`, `referenceTransactionId`, `taxes[]`.
- `paymentParams`:
  - `source`: e.g., `"TOKEN"`
  - `token`: Saved card token (e.g., `"card_PX5n06I5XRue3QX"`)


#### Example Unsigned Payload

```json
{
  "currency": "USD",
  "id": "XJ12H",
  "subtotal": 1076.64,
  "total": 2014.97,
  "email": "mscott@gmail.com",
  "tax": 488.48,
  "ipAddress": "195.151.247.241",
  "fulfilled": true,
  "orderComments": "555",
  "discount": 4,
  "items": [
    {
      "id": "xxxx-xxxx-xxxx-xxxx",
      "price": 1060,
      "sku": "ABCA-IAC",
      "quantity": 1,
      "shortDescription": "",
      "name": "iMac",
      "imageUrl": "https://example.com/images/xxxxxx.jpg",
      "selectedOptions": [
        { "name": "Color", "value": "red", "type": "CHOICE" }
      ]
    }
  ],
  "billingPerson": {
    "name": "Michael Scott",
    "companyName": "",
    "street": "555 Lackawanna Ave",
    "city": "Scranton",
    "countryCode": "US",
    "countryName": "United States",
    "postalCode": "18508",
    "stateOrProvinceCode": "PA",
    "stateOrProvinceName": "Pennsylvania",
    "phone": ""
  },
  "shippingPerson": {
    "name": "Michael Scott",
    "companyName": "",
    "street": "555 Lackawanna Ave",
    "city": "Scranton",
    "countryCode": "US",
    "countryName": "United States",
    "postalCode": "18508",
    "stateOrProvinceCode": "PA",
    "stateOrProvinceName": "Pennsylvania",
    "phone": ""
  },
  "referenceTransactionId": "transaction_65306446",
  "taxes": [ { "name": "New Tax 2", "value": 12, "total": 57.1 } ],
  "paymentParams": {
    "source": "TOKEN",
    "token": "card_PX5n06I5XRue3QX"
  }
}
```

#### Example: Signing the Payload

```javascript
const jwt = require('jsonwebtoken');
const payload = { /* fields above */ };
const signedData = jwt.sign(payload, 'your_secret_key');
```

#### Final Request Payload

```json
{ "lang": "en", "data": "<signed_jwt_token>" }
```

#### Response (200)

Returns `PaymentResponse` (see schema below).

### 3) Sale (Authorize & Capture in One Step)

**POST** `/payments/sale`

Charges the customer immediately.

- Headers, request body, and payload fields are **the same** as **Authorize**.


#### Response (200)

Returns `PaymentResponse`.

### 4) Capture an Authorized Payment

**PUT** `/payments/capture`

Converts a prior authorization into a settled charge.

#### Headers

- `client_key` (string, required)


#### Request Body (TransactionInput)

| Field | Type | Required | Description |
|  --- | --- | --- | --- |
| `lang` | string | Yes | Example: `en` |
| `data` | string (JWT) | Yes | Signed JWT with `transaction_id`. |


**Unsigned JWT payload example:**

```json
{ "transaction_id": "f45bb457-4eb5-40d3-b8df-8915180edfca" }
```

**Signing example:**

```javascript
const jwt = require('jsonwebtoken');
const payload = { transaction_id: "f45bb457-4eb5-40d3-b8df-8915180edfca" };
const signedData = jwt.sign(payload, 'your_secret_key');
```

**Final request body:**

```json
{ "lang": "en", "data": "<signed_jwt_token>" }
```

#### Response (200)

Returns `PaymentResponse`.

### 5) Void a Payment

**PUT** `/payments/void`

Voids a prior authorization or unsettled charge.

- Headers and request body are the same as **Capture** (`TransactionInput`).


#### Response (200)

Returns `PaymentResponse`.

### 6) Refund a Payment

**PUT** `/payments/refund`

Refunds a settled payment.

- Headers and request body are the same as **Capture** (`TransactionInput`).


#### Response (200)

Returns `PaymentResponse`.

## Schema: PaymentResponse

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "amount": 1200.5,
  "final_amount": 1180.5,
  "consumer_fee": 20.0,
  "currency": "USD",
  "description": "Payment for Order #12345",
  "status": "COMPLETE", // Possible statuses: (COMPLETE, PARTIAL_REFUND)
  "source": "CARD",
  "source_account": "7db04ed8-cffc-4577-8b50-d3e4c95692aa",
  "external_transaction_id": "EXT123456789",
  "entity_id": "230e8400-e29b-41d4-a716-446655440999",
  "entity_display_id": "ORD123456",
  "entity_type": "ORDER",
  "customer_id": "8ec56a2e-2c9e-43a7-8e89-202a2b9497a3",
  "customer": {
    "name": "John Doe",
    "email": "johndoe@example.com",
    "phone": "+1234567890"
  },
  "brand_id": "6ff8a7e2-4179-4d3e-9129-920ecb56c412",
  "payment_method_id": "4e8ff3b2-35f7-4e87-8a20-1cde38f4592c",
  "refunded": false,
  "settled": true,
  "source_details": {
    "card_number": "**** **** **** 4242",
    "card_brand": "Visa",
    "card_expiry": "12/25"
  },
  "error_code": null,
  "error_message": null
}
```

## Security

This API uses an **API Key** for authentication.

```http
client_key: <your_api_key>
```

## Node.js Examples

> These examples use **axios** and **jsonwebtoken**. Replace `your_secret_key`, `client_key`, tokens, and IDs with real values.


### Setup

```bash
npm install axios jsonwebtoken
```

```javascript
// config.js
module.exports = {
  API: 'https://sandbox.api.dimepay.app/dapi/v1',
  CLIENT_KEY: 'abcd1234',
  SIGNING_SECRET: 'your_secret_key'
};
```

### 1) Create Hosted Payment Page

```javascript
const axios = require('axios');
const jwt = require('jsonwebtoken');
const { API, CLIENT_KEY, SIGNING_SECRET } = require('./config');

async function createHostedPage() {
  const payload = {
    webhookUrl: 'https://webhookurl',
    redirectUrl: 'https://redirectUrl',
    checkoutUrl: 'https://checkoutUrl',
    currency: 'USD',
    id: 'XJ12H',
    subtotal: 1076.64,
    total: 2014.97,
    email: 'mscott@gmail.com'
    // ...other fields
  };

  const signedData = jwt.sign(payload, SIGNING_SECRET);

  const res = await axios.post(`${API}/payments/hosted-page`, {
    lang: 'en',
    data: signedData
  }, {
    headers: { client_key: CLIENT_KEY }
  });

  console.log('Order URL:', res.data.order_url);
}

createHostedPage().catch(err => console.error(err.response?.data || err.message));
```

### 2) Authorize Payment

```javascript
const axios = require('axios');
const jwt = require('jsonwebtoken');
const { API, CLIENT_KEY, SIGNING_SECRET } = require('./config');

async function authorizePayment() {
  const payload = {
    currency: 'USD',
    id: 'AUTH-1001',
    subtotal: 100,
    total: 100,
    email: 'buyer@example.com',
    paymentParams: { source: 'TOKEN', token: 'card_PX5n06I5XRue3QX' }
    // ...other fields like items, billingPerson, etc.
  };

  const signedData = jwt.sign(payload, SIGNING_SECRET);

  const res = await axios.post(`${API}/payments/auth`, {
    lang: 'en',
    data: signedData
  }, {
    headers: { client_key: CLIENT_KEY }
  });

  console.log('Auth Response:', res.data);
  // Save res.data.id (transaction id) for capture/void
}

authorizePayment().catch(err => console.error(err.response?.data || err.message));
```

### 3) Sale (Charge Now)

```javascript
const axios = require('axios');
const jwt = require('jsonwebtoken');
const { API, CLIENT_KEY, SIGNING_SECRET } = require('./config');

async function salePayment() {
  const payload = {
    currency: 'USD',
    id: 'SALE-1001',
    subtotal: 100,
    total: 100,
    email: 'buyer@example.com',
    paymentParams: { source: 'TOKEN', token: 'card_PX5n06I5XRue3QX' }
    // ...other fields
  };

  const signedData = jwt.sign(payload, SIGNING_SECRET);

  const res = await axios.post(`${API}/payments/sale`, {
    lang: 'en',
    data: signedData
  }, {
    headers: { client_key: CLIENT_KEY }
  });

  console.log('Sale Response:', res.data);
  // Save res.data.id for refund if needed
}

salePayment().catch(err => console.error(err.response?.data || err.message));
```

### 4) Capture Auth

```javascript
const axios = require('axios');
const jwt = require('jsonwebtoken');
const { API, CLIENT_KEY, SIGNING_SECRET } = require('./config');

async function capturePayment() {
  const transactionId = 'f45bb457-4eb5-40d3-b8df-8915180edfca'; // from auth
  const signedData = jwt.sign({ transaction_id: transactionId }, SIGNING_SECRET);

  const res = await axios.put(`${API}/payments/capture`, {
    lang: 'en',
    data: signedData
  }, {
    headers: { client_key: CLIENT_KEY }
  });

  console.log('Capture Response:', res.data);
}

capturePayment().catch(err => console.error(err.response?.data || err.message));
```

### 5) Void Auth

```javascript
const axios = require('axios');
const jwt = require('jsonwebtoken');
const { API, CLIENT_KEY, SIGNING_SECRET } = require('./config');

async function voidPayment() {
  const transactionId = 'f45bb457-4eb5-40d3-b8df-8915180edfca';
  const signedData = jwt.sign({ transaction_id: transactionId }, SIGNING_SECRET);

  const res = await axios.put(`${API}/payments/void`, {
    lang: 'en',
    data: signedData
  }, {
    headers: { client_key: CLIENT_KEY }
  });

  console.log('Void Response:', res.data);
}

voidPayment().catch(err => console.error(err.response?.data || err.message));
```

### 6) Refund Sale

```javascript
const axios = require('axios');
const jwt = require('jsonwebtoken');
const { API, CLIENT_KEY, SIGNING_SECRET } = require('./config');

async function refundPayment() {
  const transactionId = 'f45bb457-4eb5-40d3-b8df-8915180edfca'; // original sale transaction id
  const signedData = jwt.sign({ transaction_id: transactionId, amount: refundAmount }, SIGNING_SECRET);

  const res = await axios.put(`${API}/payments/refund`, {
    lang: 'en',
    data: signedData
  }, {
    headers: { client_key: CLIENT_KEY }
  });

  console.log('Refund Response:', res.data);
}

refundPayment().catch(err => console.error(err.response?.data || err.message));
```