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

# Payins

> Accept payments globally with Zuba payins

## Overview

Payins enable you to accept payments from customers through manual bank transfers. The Zuba platform processes these payments and credits funds to your account while maintaining full transparency and compliance.

## Manual Deposits

Traditional bank transfers where customers manually send funds to your designated account. When you create a manual deposit, Zuba generates unique bank account details (IBAN and reference) for your customer to transfer funds to.

<CodeGroup>
  ```bash curl theme={"dark"}
  curl -X POST "https://api.sandbox.zuba.com/v1/deposits" \
    -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "amount": "500.00",
      "currency": "EUR",
      "clientRef": "DEPOSIT-REF-001",
      "description": "Subscription payment"
    }'
  ```

  ```javascript JavaScript theme={"dark"}
  const deposit = await fetch('https://api.sandbox.zuba.com/v1/deposits', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      amount: '500.00',
      currency: 'EUR',
      clientRef: 'DEPOSIT-REF-001',
      description: 'Subscription payment'
    })
  });

  const data = await deposit.json();
  // { id: 'dep_xxx', iban: 'DE89...', bic: 'DEUTDEFF', reference: 'REF123', status: 'pending' }
  ```
</CodeGroup>

## Payment Lifecycle

```mermaid theme={"dark"}
sequenceDiagram
    participant Customer
    participant Your App
    participant Zuba API
    participant Bank
    participant Ledger

    Customer->>Your App: Initiate Payment
    Your App->>Zuba API: Create Deposit
    Zuba API-->>Your App: IBAN & Reference
    Your App-->>Customer: Show Instructions
    Customer->>Bank: Transfer Funds
    Bank->>Zuba API: Receive Transfer
    Zuba API->>Ledger: Credit Account
    Zuba API-->>Your App: Webhook Notification
    Your App-->>Customer: Payment Confirmed
```

## Payment Statuses

| Status       | Description                                 | Actions Available  |
| ------------ | ------------------------------------------- | ------------------ |
| `pending`    | Deposit created, awaiting customer transfer | Monitor, Cancel    |
| `processing` | Transfer detected, being verified           | Track status       |
| `completed`  | Funds received and credited to your account | View receipt       |
| `failed`     | Deposit expired or transfer failed          | Review, Create new |
| `cancelled`  | Deposit cancelled before completion         | View details       |

## Checking Deposit Status

<CodeGroup>
  ```bash curl theme={"dark"}
  curl -X GET "https://api.sandbox.zuba.com/v1/deposits/dep_1234567890" \
    -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
  ```

  ```javascript JavaScript theme={"dark"}
  const status = await fetch(`https://api.sandbox.zuba.com/v1/deposits/${depositId}`, {
    headers: {
      'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
    }
  });

  const data = await status.json();
  console.log(data.status); // pending, processing, completed, etc.
  ```
</CodeGroup>

## Listing Deposits

Retrieve deposits for your account as a paginated list, newest first. Filter with `status`, and page with `limit` (1–100, default 20) plus `cursor`:

<CodeGroup>
  ```bash curl theme={"dark"}
  curl -X GET "https://api.sandbox.zuba.com/v1/deposits?status=completed&limit=20" \
    -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
  ```

  ```javascript JavaScript theme={"dark"}
  const page = await fetch('https://api.sandbox.zuba.com/v1/deposits?status=completed&limit=20', {
    headers: {
      'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
    }
  });

  const { deposits, nextCursor, hasMore } = await page.json();
  // deposits: array of deposit objects (id, status, amount, currency, method, clientRef, timestamps)

  if (hasMore) {
    const next = await fetch(
      `https://api.sandbox.zuba.com/v1/deposits?limit=20&cursor=${encodeURIComponent(nextCursor)}`,
      { headers: { 'Authorization': 'Bearer YOUR_ACCESS_TOKEN' } }
    );
  }
  ```
</CodeGroup>

Treat `nextCursor` as an opaque token: pass it back verbatim in the `cursor` query parameter to fetch the next page, and stop when `hasMore` is `false`. An invalid `cursor`, `limit`, or `status` value returns a `400` with field-level details.

## Cancelling Pending Deposits

Cancel deposits that haven't been completed yet:

<CodeGroup>
  ```bash curl theme={"dark"}
  curl -X POST "https://api.sandbox.zuba.com/v1/deposits/dep_1234567890/cancel" \
    -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
  ```

  ```javascript JavaScript theme={"dark"}
  const result = await fetch(`https://api.sandbox.zuba.com/v1/deposits/${depositId}/cancel`, {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
    }
  });

  const data = await result.json();
  // { success: true, message: 'Deposit cancelled successfully' }
  ```
</CodeGroup>

<Note>
  Only deposits in `pending` status can be cancelled. Once a deposit is `processing` or `completed`, it cannot be cancelled.
</Note>

## Supported Countries & Currencies

### European Union (SEPA Zone)

* **Countries**: Germany, France, Spain, Italy, Netherlands, Belgium, Austria, Portugal, Finland, Ireland, and more
* **Currency**: EUR
* **Settlement**: 1-2 business days

### United Kingdom

* **Currency**: GBP
* **Settlement**: 1-2 business days via UK bank transfer

### Supported Currencies

* **Major Fiat**: EUR, GBP, USD, CAD
* **Settlement Times**: Vary by currency and banking network

## Webhooks & Notifications

Set up webhooks to receive real-time updates on deposit status changes:

```json Webhook Payload Example theme={"dark"}
{
  "id": "evt_1234567890",
  "type": "deposit.completed",
  "data": {
    "depositId": "dep_1234567890",
    "method": "manual_deposit",
    "amount": "500.00",
    "currency": "EUR",
    "status": "completed",
    "completedAt": "2024-03-15T10:30:00Z"
  },
  "timestamp": "2024-03-15T10:30:05Z"
}
```

### Webhook Events

| Event                | Description             | When Triggered                     |
| -------------------- | ----------------------- | ---------------------------------- |
| `deposit.created`    | Deposit created         | When deposit request is initiated  |
| `deposit.processing` | Deposit being processed | Transfer detected from customer    |
| `deposit.completed`  | Deposit completed       | Funds received and credited        |
| `deposit.failed`     | Deposit failed          | Transfer failed or deposit expired |
| `deposit.cancelled`  | Deposit cancelled       | User or system cancellation        |

## Error Handling

Common deposit errors and solutions:

| Error Code             | Description                      | Solution                                    |
| ---------------------- | -------------------------------- | ------------------------------------------- |
| `INVALID_AMOUNT`       | Amount is invalid or too large   | Check amount format and limits              |
| `UNSUPPORTED_CURRENCY` | Currency not supported           | Use supported currency (EUR, GBP, USD, CAD) |
| `DEPOSIT_EXPIRED`      | Deposit reference expired        | Create new deposit                          |
| `INVALID_REFERENCE`    | Transfer reference doesn't match | Ensure customer uses exact reference        |
| `DUPLICATE_CLIENT_REF` | Client reference already used    | Use unique clientRef for each deposit       |

## Best Practices

<AccordionGroup>
  <Accordion title="Deposit Creation">
    * Always include unique `clientRef` for idempotency and reconciliation
    * Provide clear instructions to customers about IBAN and reference
    * Set reasonable timeout periods and communicate them to customers
    * Store deposit IDs for status tracking and customer support
  </Accordion>

  <Accordion title="Status Monitoring">
    * Implement webhook endpoints for real-time updates
    * Use exponential backoff when polling deposit status
    * Handle all possible status transitions in your code
    * Log deposit events for audit and debugging
  </Accordion>

  <Accordion title="Customer Experience">
    * Display IBAN, BIC, and payment reference clearly
    * Show expected settlement times (1-2 business days for SEPA)
    * Send confirmation emails with payment instructions
    * Implement proper error messaging for failed deposits
    * Provide customer support contact for payment issues
  </Accordion>

  <Accordion title="Security">
    * Validate webhook signatures to prevent spoofing
    * Use HTTPS for all API communications
    * Never log sensitive customer payment data
    * Implement proper access controls for deposit endpoints
  </Accordion>
</AccordionGroup>

## Integration Example

### React Deposit Component

```javascript theme={"dark"}
import { useState } from 'react';

function DepositForm() {
  const [loading, setLoading] = useState(false);
  const [deposit, setDeposit] = useState(null);

  const createDeposit = async (amount, currency) => {
    setLoading(true);
    try {
      const response = await fetch('/api/create-deposit', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          amount,
          currency,
          clientRef: `DEP-${Date.now()}`
        })
      });

      const data = await response.json();
      setDeposit(data);
    } catch (error) {
      console.error('Deposit creation failed:', error);
    } finally {
      setLoading(false);
    }
  };

  return (
    <div>
      <button
        onClick={() => createDeposit('500.00', 'EUR')}
        disabled={loading}
      >
        {loading ? 'Creating Deposit...' : 'Deposit €500.00'}
      </button>

      {deposit && (
        <div className="payment-instructions">
          <h3>Bank Transfer Instructions</h3>
          <div>
            <strong>IBAN:</strong> {deposit.iban}
          </div>
          <div>
            <strong>BIC:</strong> {deposit.bic}
          </div>
          <div>
            <strong>Reference:</strong> {deposit.reference}
          </div>
          <div>
            <strong>Amount:</strong> {deposit.amount} {deposit.currency}
          </div>
          <p>
            Please use the reference code exactly as shown.
            Your payment will be credited within 1-2 business days.
          </p>
        </div>
      )}
    </div>
  );
}
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Payouts" icon="money-bill-transfer" href="/concepts/payouts">
    Send money globally to beneficiaries
  </Card>

  <Card title="Webhook Setup" icon="webhook" href="/guides/webhooks">
    Configure real-time deposit notifications
  </Card>

  <Card title="Ledger System" icon="book-open" href="/concepts/ledger">
    Track transactions with double-entry accounting
  </Card>

  <Card title="API Reference" icon="code" href="/api-reference/introduction">
    Complete API documentation
  </Card>
</CardGroup>
