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

# Transaction Flow

> Complete payment flow combining Payin and Payout APIs

## Overview

This guide explains the complete transaction flow for accepting payments via card (Payin API) and delivering funds to recipients (Payout API). This integrated flow allows you to accept payments from customers and automatically transfer funds to recipients.

## Complete Transaction Flow

```mermaid theme={null}
sequenceDiagram
    participant Customer
    participant Frontend
    participant Approvely
    participant Backend
    participant CashQ
    participant Recipient

    Customer->>Frontend: Enter card details
    Frontend->>Approvely: Tokenize card (iframe)
    Approvely-->>Frontend: Return nonce token
    Frontend->>Backend: Submit payment request
    Backend->>Approvely: Charge API with nonce
    Approvely-->>Backend: Return approvelyId
    Backend->>CashQ: KYC verification
    CashQ-->>Backend: KYC approved
    Backend->>CashQ: Check Transfer with approvelyId
    Backend->>CashQ: Transfer with approvelyId
    CashQ->>Recipient: Funds delivered
```

## Step-by-Step Process

### Phase 1: Card Payment (Payin)

<Steps>
  <Step title="Customer enters card details">
    Customer fills out the payment form on your website with their card information

    <Info>
      Card data is entered directly into Approvely's secure iframe, never touching your servers.
    </Info>
  </Step>

  <Step title="Tokenize card data">
    Your frontend calls Approvely's tokenization API to convert card data into a secure nonce token

    ```javascript theme={null}
    const result = await cardForm.getNonceToken();
    const nonceToken = 'nonce-' + result.nonce;
    ```

    <Check>
      Nonce token received (e.g., `nonce-pft4uav4cker5g8bk3db`)
    </Check>
  </Step>

  <Step title="Submit payment to backend">
    Frontend sends the nonce token to your backend server along with payment details

    ```javascript theme={null}
    const response = await fetch('/api/process-payment', {
      method: 'POST',
      body: JSON.stringify({
        nonce: nonceToken,
        amount: 100,
        recipient_phone: '5551234568',
        cardholder_name: 'John Doe'
      })
    });
    ```
  </Step>

  <Step title="Charge the card">
    Your backend calls Approvely's charge endpoint with the nonce token

    ```javascript theme={null}
    const chargeResponse = await fetch(
      'https://api.sandbox.approvelygateway.com/api/v2/transactions/charge',
      {
        method: 'POST',
        headers: {
          'Authorization': `Basic ${credentials}`,
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          amount: 100,
          source: nonceToken,
          expiry_month: 10,
          expiry_year: 2028,
          billing_info: { /* ... */ }
        })
      }
    );

    const chargeData = await chargeResponse.json();
    const approvelyId = chargeData.id; // Save this ID
    ```

    <Check>
      Payment approved and `approvelyId` received (e.g., `txn_1234567890`)
    </Check>
  </Step>
</Steps>

### Phase 2: Fund Transfer (Payout)

<Steps>
  <Step title="Verify recipient KYC">
    Check if the recipient is KYC verified and can receive the transfer amount

    ```javascript theme={null}
    const kycResponse = await fetch(
      `https://api.cashqbot.com/api/kyc/${recipientPhone}`,
      {
        headers: { 'API-KEY': cashqApiKey }
      }
    );

    const kycData = await kycResponse.json();

    if (parseFloat(kycData.money_limit) < amount) {
      throw new Error('Amount exceeds recipient limit');
    }
    ```

    <Check>
      Recipient KYC verified and can receive the amount
    </Check>
  </Step>

  <Step title="Check transfer">
    Validate the transfer details before executing

    ```javascript theme={null}
    const checkResponse = await fetch(
      'https://api.cashqbot.com/api/checkTransfer',
      {
        method: 'POST',
        headers: {
          'API-KEY': cashqApiKey,
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          id: generateTransferId(),
          sender_phone: merchantPhone,
          receiver_phone: recipientPhone,
          amount: amount.toString(),
          receiver_country: 'MX',
          attribute: [
            {
              name: 'approvelyId',
              value: {{approvelyId}}
            },
             /* other attributes... */
          ]
        })
      }
    );
    ```

    <Info>
      The `approvelyId` is included in the `attribute` array with name `'approvelyId'` to link the payout with the payin transaction.
    </Info>
  </Step>

  <Step title="Execute transfer">
    Execute the money transfer to the recipient

    ```javascript theme={null}
    const transferResponse = await fetch(
      'https://api.cashqbot.com/api/transfer',
      {
        method: 'POST',
        headers: {
          'API-KEY': cashqApiKey,
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          id: transferId,
          sender_phone: merchantPhone,
          receiver_phone: recipientPhone,
          amount: amount.toString(),
          receiver_country: 'MX',
          attribute: [
            {
              name: 'approvelyId',
              value: {{approvelyId}}
            },
            /* other attributes... */
          ]
        })
      }
    );

    const transferData = await transferResponse.json();
    ```

    <Check>
      Transfer initiated successfully
    </Check>
  </Step>

  <Step title="Monitor transfer status">
    Poll the transfer status until completion

    ```javascript theme={null}
    const finalStatus = await pollTransferStatus(transferId);

    if (finalStatus.state === 60) {
      // Transfer successful - funds delivered to recipient
      console.log('Transfer completed successfully');
    } else if (finalStatus.state === 80) {
      // Transfer failed - may need to refund the card charge
      console.error('Transfer failed');
    }
    ```

    <Check>
      Funds successfully delivered to recipient
    </Check>
  </Step>
</Steps>

## Linking Transactions

The `approvelyId` is crucial for linking the card payment with the money transfer. Include it in the `attribute` array:

```json theme={null}
{
  "attribute": [
    {
      "name": "approvelyId",
      "value": "1234567890"
    },
    /* other attributes... */
  ]
}
```

This allows you to:

* Track which card payment funded which transfer
* Reconcile transactions across both systems
* Handle refunds if transfers fail
* Generate accurate financial reports

## Error Handling

<AccordionGroup>
  <Accordion title="Card charge fails">
    **Action:** Return error to customer, don't proceed with transfer

    ```javascript theme={null}
    if (chargeData.status !== 'approved') {
      return res.status(400).json({
        error: 'Card declined',
        message: chargeData.error.message
      });
    }
    ```
  </Accordion>

  <Accordion title="Recipient KYC limit exceeded">
    **Action:** Refund the card charge, inform customer

    ```javascript theme={null}
    if (parseFloat(kycData.money_limit) < amount) {
      await refundCharge(approvelyId);
      return res.status(400).json({
        error: 'Recipient limit exceeded',
        kyc_url: kycData.kyc_url
      });
    }
    ```
  </Accordion>

  <Accordion title="Transfer validation fails">
    **Action:** Refund the card charge, return error

    ```javascript theme={null}
    if (!checkData.success) {
      await refundCharge(approvelyId);
      return res.status(400).json({
        error: 'Transfer validation failed'
      });
    }
    ```
  </Accordion>

  <Accordion title="Transfer execution fails">
    **Action:** Refund the card charge, log for investigation

    ```javascript theme={null}
    if (!transferData.success) {
      await refundCharge(approvelyId);
      logFailedTransfer(approvelyId, transferId);
      return res.status(400).json({
        error: 'Transfer failed'
      });
    }
    ```
  </Accordion>
</AccordionGroup>

## API References

<CardGroup cols={2}>
  <Card title="Payin API" icon="credit-card" href="/payin/introduction">
    Learn about card tokenization and charging
  </Card>

  <Card title="Payout API" icon="money-bill-transfer" href="/payout/balance">
    Learn about money transfers and KYC verification
  </Card>

  <Card title="Charge Endpoint" icon="bolt" href="/payin/charge">
    Process card payments
  </Card>

  <Card title="Transfer Endpoint" icon="paper-plane" href="/payout/transfer">
    Execute money transfers
  </Card>
</CardGroup>
