> ## Documentation Index
> Fetch the complete documentation index at: https://developer.utgl.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Partner Connect API

> Complete guide to integrating merchant payment processing with UTGL card services

The Partner Connect API enables merchants and service providers to integrate with UTGL's card services for securely binding customer payment cards and processing transactions. This API is designed for e-commerce platforms, payment gateways, and other merchant applications that need to accept payments from UTGL cardholders.

<Note>
  **Terminology Note:** While this API is called "Partner Connect," it's designed specifically for **merchants** who want to accept payments from UTGL cardholders. The term "partner" refers to external businesses integrating with UTGL's payment infrastructure.
</Note>

***

## Overview

The Partner Connect API provides two main capabilities:

1. **Card Binding** - Securely link customer payment cards to your merchant system
2. **Transaction Processing** - Authorize, capture, void, and refund payments using bound cards

***

## Architecture & Authentication

The Partner Connect API uses a simpler authentication model compared to the Issuing API:

* **HTTP Basic Authentication** - Username/password credentials
* **Bearer Token (JWT)** - Token-based authentication

Both authentication methods are supported. Choose the one that best fits your integration architecture.

***

## Complete Workflow

### Phase 1: Card Binding

Before processing any transactions, you must first bind a customer's card to your merchant system. This is a one-time process per card.

#### Step 1: Initiate Card Binding

The merchant initiates the binding process by sending the customer's full PAN (Primary Account Number).

```mermaid theme={null}
sequenceDiagram
    participant Merchant
    participant API
    participant Cardholder
    
    Merchant->>API: POST /card-binding/initiate<br/>{fullPan}
    API->>Cardholder: Send OTP via SMS/Email
    API->>Merchant: {verificationId, code, maskedPan, codeExpiry}
    Note over Merchant: Store verificationId securely
    Note over Cardholder: Receive OTP code
```

**Response includes:**

* `verificationId` - Unique identifier for this binding attempt
* `code` - Verification code sent to cardholder (also returned for testing)
* `maskedPan` - Masked card number for display
* `codeExpiry` - Expiration timestamp for the code

#### Step 2: Confirm Card Binding

The cardholder enters the verification code they received. The merchant submits this code along with the `verificationId` to complete the binding.

```mermaid theme={null}
sequenceDiagram
    participant Merchant
    participant API
    participant Cardholder
    
    Cardholder->>Merchant: Enters verification code
    Merchant->>API: POST /card-binding/confirm<br/>{verificationId, code}
    API->>Merchant: {cardId, bindingStatus, cardFace, expirationDate}
    Note over Merchant: Store cardId for future transactions
```

**Response includes:**

* `cardId` - **Critical:** Store this UUID securely. It's required for all future transactions with this card.
* `bindingStatus` - Confirms successful binding
* `cardFace` - Card brand image URL
* `expirationDate` - Card expiration date

### Phase 2: Transaction Processing

Once a card is bound, you can process transactions. The transaction lifecycle follows a standard authorization-capture pattern with support for voids and refunds.

#### Transaction Lifecycle Diagram

The following diagram shows the complete transaction lifecycle:

```mermaid theme={null}
stateDiagram-v2
    [*] --> Verify: Initiate Transaction
    Verify --> Purchase: OTP Received
    Purchase --> Locked: Authorization Success
    Purchase --> [*]: Authorization Failed
    
    Locked --> Captured: Capture Funds
    Locked --> Void: Release Authorization
    
    Captured --> Refunded: Refund Transaction
    Void --> [*]: Transaction Complete
    Refunded --> [*]: Transaction Complete
    Captured --> [*]: Transaction Complete
```

### Transaction Processing Steps

#### Step 1: Verify Transaction

Before authorizing a payment, verify the transaction parameters and trigger OTP delivery to the cardholder.

```mermaid theme={null}
sequenceDiagram
    participant Merchant
    participant API
    participant Cardholder
    
    Merchant->>API: POST /transactions/verify<br/>{cardId, amount, currency, description}
    API->>Cardholder: Send OTP via SMS/Email
    API->>Merchant: {success: true}
    Note over Cardholder: Receive OTP code
```

#### Step 2: Authorize Purchase

The cardholder enters the OTP code. The merchant submits the transaction details along with the OTP to authorize the payment.

```mermaid theme={null}
sequenceDiagram
    participant Merchant
    participant API
    participant Cardholder
    participant Card Account
    
    Cardholder->>Merchant: Enters OTP code
    Merchant->>API: POST /transactions/purchase<br/>{cardId, amount, currency, description, otpToken}
    API->>Card Account: Reserve funds (lock)
    API->>Merchant: {transactionId, status: "locked", amountAuthorized}
    Note over Merchant: Store transactionId
    Note over Card Account: Funds held (not yet transferred)
```

**Response includes:**

* `transactionId` - **Critical:** Store this UUID. Required for capture, release, or refund operations.
* `status` - Will be `"locked"` after successful authorization
* `amountAuthorized` - The amount that was authorized
* `authorizationExpiry` - When the authorization expires

#### Step 3: Capture Funds

After fulfilling the order or providing the service, capture the authorized funds to complete the payment.

```mermaid theme={null}
sequenceDiagram
    participant Merchant
    participant API
    participant Card Account
    participant Merchant Account
    
    Merchant->>API: POST /transactions/capture<br/>{transactionId, amount}
    API->>Card Account: Debit funds
    API->>Merchant Account: Credit funds
    API->>Merchant: {transactionId, status: "captured", amountCaptured}
    Note over Merchant Account: Funds received
```

**Important Notes:**

* Capture must occur before `authorizationExpiry`
* You can capture less than the authorized amount (partial capture)
* Once captured, funds are transferred to your merchant account

#### Alternative: Release Authorization

If you need to cancel an order before fulfillment, release (void) the authorization to free the customer's funds.

```mermaid theme={null}
sequenceDiagram
    participant Merchant
    participant API
    participant Card Account
    
    Merchant->>API: POST /transactions/release<br/>{transactionId}
    API->>Card Account: Release hold
    API->>Merchant: {transactionId, status: "void"}
    Note over Card Account: Funds available again
```

**Important Notes:**

* Release can only be done on `locked` transactions
* Once released, the transaction cannot be captured
* This operation cannot be reversed

#### Step 4: Process Refunds (if needed)

For captured transactions, you can issue full or partial refunds.

```mermaid theme={null}
sequenceDiagram
    participant Merchant
    participant API
    participant Merchant Account
    participant Card Account
    
    Merchant->>API: POST /transactions/refund<br/>{transactionId, amount, currency, reason, description}
    API->>Merchant Account: Debit refund amount
    API->>Card Account: Credit refund amount
    API->>Merchant: {transactionId, refundTransactionId, status: "refunded"}
    Note over Card Account: Funds returned
```

**Important Notes:**

* Refunds can only be processed on `captured` transactions
* You can issue multiple partial refunds up to the captured amount
* Each refund generates a unique `refundTransactionId`

***

## Transaction Status Lifecycle

Understanding transaction statuses is crucial for proper integration:

| Status         | Description                                                                                             | Next Possible Actions      |
| -------------- | ------------------------------------------------------------------------------------------------------- | -------------------------- |
| **`locked`**   | Funds are authorized and reserved on the cardholder's account, but not yet transferred to the merchant. | `capture` or `release`     |
| **`captured`** | Funds have been successfully transferred from the cardholder to the merchant account.                   | `refund` (full or partial) |
| **`void`**     | Authorization was cancelled before capture. Funds are released back to the cardholder.                  | None (final state)         |
| **`refunded`** | Funds from a captured transaction have been returned to the cardholder.                                 | None (final state)         |

### Status Transition Rules

<Warning>
  **Important:** Not all status transitions are allowed. Follow these rules:

  * **`locked`** → Can only transition to `captured` or `void`
  * **`captured`** → Can only transition to `refunded` (via refund operation)
  * **`void`** → Final state, no further actions
  * **`refunded`** → Final state, no further actions
</Warning>

***

## Integration Best Practices

### Security

1. **Never log sensitive data:**
   * Full PANs
   * Verification codes (OTP)
   * Card IDs (store securely, don't log)

2. **Store securely:**
   * `cardId` - Required for all future transactions
   * `transactionId` - Required for capture/release/refund operations

3. **Handle expiration:**
   * Verification codes expire (check `codeExpiry`)
   * Authorizations expire (check `authorizationExpiry`)

### Error Handling

The API uses standard HTTP status codes with detailed error responses:

* **400 Bad Request** - Invalid parameters or malformed request
* **404 Not Found** - Resource doesn't exist or invalid state
* **406 Not Acceptable** - Transaction declined or failed
* **409 Conflict** - Resource conflict (e.g., already bound)
* **500 Internal Server Error** - Server-side error

Each error response includes a `code` and `message` field for programmatic handling.

### Idempotency

* Card binding requests are idempotent - duplicate requests return the same `verificationId`
* Transaction operations should be idempotent on your side using unique identifiers

### Timing Considerations

* **Authorization expiry:** Capture or release before `authorizationExpiry`
* **Code expiry:** Complete binding confirmation before `codeExpiry`
* **Network timeouts:** Implement retry logic with exponential backoff

***

## Quick Reference

### Card Binding Endpoints

| Endpoint                                          | Method | Purpose                        |
| ------------------------------------------------- | ------ | ------------------------------ |
| `/merchant/partner-connect/card-binding/initiate` | POST   | Start card binding process     |
| `/merchant/partner-connect/card-binding/confirm`  | POST   | Complete card binding with OTP |

### Transaction Endpoints

| Endpoint                                          | Method | Purpose                                      |
| ------------------------------------------------- | ------ | -------------------------------------------- |
| `/merchant/partner-connect/transactions/verify`   | POST   | Initiate transaction verification (send OTP) |
| `/merchant/partner-connect/transactions/purchase` | POST   | Authorize a purchase transaction             |
| `/merchant/partner-connect/transactions/capture`  | POST   | Capture authorized funds                     |
| `/merchant/partner-connect/transactions/release`  | POST   | Void/release authorization                   |
| `/merchant/partner-connect/transactions/refund`   | POST   | Refund captured transaction                  |

***

## Next Steps

* Explore the [Card Binding endpoints](/merchant/partner-connect/card-binding/initiate) to get started
* Review [Transaction endpoints](/merchant/partner-connect/transactions/purchase) for payment processing
* Check the [OpenAPI specification](/merchant/partner-connect/partner-connect.yaml) for complete API details
