# Add or take out customer credit

```http
POST https://secure.yoprint.com/v1/api/store/{team_slug}/customer/{hash_id}/credit
```

- API version: v1
- Operation ID: `v1_public_customer_credit_store`
- Section: Customers › [Customer credit](https://developer.yoprint.com/reference/customer-credit.md)
- Web page: https://developer.yoprint.com/reference/customer-credit/v1-customer-credit-store/
- Authentication: `Authorization: Bearer YOUR_API_KEY`

Adds credit to the customer's balance (`action: deposit`) or takes it out (`action: withdraw`), and returns the entry. This is Issue Customer Credit in YoPrint. Credit can then pay the customer's sales orders.

Send a whole number of thousandths for `amount`: `50000` is 50.00. The sign is ignored; `action` decides the direction.

## Permission

Needs the Manage Customers permission: "Manage All" for any customer, or "Manage Assigned to User" for customers assigned to you.

## Business rules

- A withdrawal can't be more than the credit available now: `wallet_fund` less credit from Customer Portal payments that is held (for example by a dispute, see `held_credit`) or set aside for a payment or refund in progress. None is allowed while the balance is negative (422 "Insufficient Customer Balance to perform such action").
- A deleted customer is not found (404). Restore it first.
- Customers synced from Shopify are read-only here: changes are refused with 422 `validation_error` "External customers are read-only. Manage changes from Shopify." System customers (`is_system: true`) are refused the same way ("System customer cannot be modified or deleted.").

## Side effects

- Changes the customer's credit balance (`wallet_fund`) at once.
- Sends `customer_credit.deposited` or `customer_credit.withdrew`.
- Open Customer Portal pages of the customer are told to refresh.

## Path parameters

- `team_slug` (string, required): Your team slug, shown as Team ID next to your API key in Profile. Example `your-team`.
- `hash_id` (string, required): The customer's id (`id` from List customers or Create a customer). A hash id from an earlier answer; unique keys and document numbers (such as `PO0042`) don't work here. Example `EDhVUaC6jbLbed`.

## Request body

Content type `application/json`, required.

Fields:

- `action` (string, required): One of: `"deposit"`, `"withdraw"`.
- `amount` (integer, required): Send a whole number of thousandths: `50000` is 50.00. A number with decimals is refused with 422.
- `payment_method_id` (string, optional): One of your team's payment methods: how the money came in or went out.
- `reference_id` (string, optional): Your reference, such as a cheque or transfer number.

### Example request

```bash
curl -X POST 'https://secure.yoprint.com/v1/api/store/your-team/customer/EDhVUaC6jbLbed/credit' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Accept: application/json' \
  -H 'X-Yoprint-Decimal-Format: exact-v1' \
  -H 'Content-Type: application/json' \
  -d '{
    "action": "deposit",
    "amount": 50000,
    "payment_method_id": "6nz3Vu9sFR4dxM",
    "reference_id": "CHQ-1001"
  }'
```

Another example: Take out 20.00:

```bash
curl -X POST 'https://secure.yoprint.com/v1/api/store/your-team/customer/EDhVUaC6jbLbed/credit' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Accept: application/json' \
  -H 'X-Yoprint-Decimal-Format: exact-v1' \
  -H 'Content-Type: application/json' \
  -d '{
    "action": "withdraw",
    "amount": 20000
  }'
```

## Response

`200` Successful response.

Fields:

- `data` (object, required)
  - `action` (string, required): The specific action that created the entry: Manual entries: - `CUSTOMER_DEPOSIT`: credit added by hand (created by this API). - `CUSTOMER_WITHDRAW`: credit taken out by hand (created by this API). - `CUSTOMER_CREDIT_WITHDRAW`: credit used to pay a sales order. - `CUSTOMER_CREDIT_DEPOSIT`: a sales order payment refunded to credit. System entries: - `CUSTOMER_CHECKOUT_FUNDING`: a Customer Portal payment received into credit. - `CUSTOMER_CHECKOUT_<KIND>`: an adjustment to a portal payment (such as `CUSTOMER_CHECKOUT_REFUND`). - `CUSTOMER_CREDIT_RECOVERY`: credit a refund took back. - `CUSTOMER_CREDIT_RESTORED`: credit restored after a failed refund. - Overpayment actions for `CUSTOMER_SPILLED_OVER_*` entries.
  - `amount` (integer | number | string, required): Positive for credit added, negative for credit taken out. Thousandths, an older encoding: `12500` is 12.50. Usually a whole number; an amount finer than a thousandth comes back as a number with a fraction (`1234.5` is 1.2345), or as a string (`"1234.5"`) when you send `X-Yoprint-Decimal-Format: exact-v1`. See [Money and quantities](/concepts/money-and-quantities/).
  - `credit_source` (object | null, required): Where the credit came from or went: on credit issued from a payment, credit applied to a sales order, and credit a refund or a lost dispute took back or gave back. Null on other entries.
    - `customer_payment_funding_id` (string | null, required): The Customer Portal payment's key, when the credit came from one. Null otherwise.
    - `kind` (string, required): `issued`: credit issued from a sales order payment. `returned`: Issue credit took back credit a Customer Portal payment had left on the order. `order_deleted_credit`: issued credit whose sales order was later deleted. `applied`: credit applied to a sales order. `refund`: credit the customer had already spent, owed back after a refund. `credit_used_for_refund` and `credit_taken_back`: credit a refund took back without making the balance negative; nothing is owed. `refund_failed`: that credit given back because the refund failed. `chargeback`: taken back by a lost dispute. `refund_and_chargeback`: taken back by a lost dispute after a refund during it. `order_deleted`: taken back for a deleted sales order. One of: `"issued"`, `"returned"`, `"order_deleted_credit"`, `"applied"`, `"refund"`, `"credit_used_for_refund"`, `"credit_taken_back"`, `"refund_failed"`, `"chargeback"`, `"refund_and_chargeback"`, `"order_deleted"`.
    - `order_hash_id` (string | null, required): The sales order's id. Null when no single order is involved, or when the order of an `applied` entry was deleted.
    - `order_reference` (string | null, required): That sales order's number, such as `SO1001`. Not an id.
    - `payment_label` (string, required): The payment the credit came from, as YoPrint names it, such as "Stripe payment", "Cash payment" or "Customer credit".
  - `date` (string (date-time), required): When the entry was made.
  - `direction` (string, required): Whether the entry added credit or took it out. One of: `"INCREASE"`, `"DECREASE"`.
  - `id` (string, required)
  - `subtype` (string, required): The category of the credit entry: - `TRANSFER`: all `MANUAL` entries. - `CUSTOMER_CHECKOUT_FUNDING`: a Customer Portal payment received into customer credit. - `CUSTOMER_CHECKOUT_FUNDING_ADJUSTMENT`: a later change to a portal payment, such as a refund or lost dispute. - `CUSTOMER_SPILLED_OVER_GATEWAY_PAYMENT`: an online payment overpayment moved into credit. - `CUSTOMER_SPILLED_OVER_GATEWAY_PAYMENT_REFUND`: a refund of an overpayment. - `CUSTOMER_SPILLED_OVER_GATEWAY_REFUND`: an online refund overpayment moved into credit. - `CUSTOMER_CREDIT_RECOVERY`: credit a refund took back. - `CUSTOMER_CREDIT_RESTORED`: credit given back because that refund failed. One of: `"TRANSFER"`, `"CUSTOMER_CHECKOUT_FUNDING"`, `"CUSTOMER_CHECKOUT_FUNDING_ADJUSTMENT"`, `"CUSTOMER_SPILLED_OVER_GATEWAY_PAYMENT"`, `"CUSTOMER_SPILLED_OVER_GATEWAY_PAYMENT_REFUND"`, `"CUSTOMER_SPILLED_OVER_GATEWAY_REFUND"`, `"CUSTOMER_CREDIT_RECOVERY"`, `"CUSTOMER_CREDIT_RESTORED"`.
  - `type` (string, required): Whether the entry was made by a person or by YoPrint: - `MANUAL`: credit added or taken out by hand, credit used to pay a sales order, and sales order payments refunded to credit. - `SYSTEM`: entries YoPrint creates automatically, including Customer Portal payments received into credit and their adjustments (such as refunds), online overpayments, and credit recovered or restored. One of: `"MANUAL"`, `"SYSTEM"`.
  - `credit_source_payment_id` (string | null, optional): Those two kinds only: the id of the sales order payment the credit came from.
  - `currency_iso` (string | null, optional): Customer Portal payment entries only: the payment's currency, such as `USD`.
  - `customer_id` (string | null, optional)
  - `customer_payment_application_id` (string | null, optional)
  - `customer_payment_checkout_id` (string | null, optional): Customer Portal payment entries only: the key of the checkout the payment was made in, or null.
  - `customer_payment_funding_id` (string | null, optional): Customer Portal payment entries only (`CUSTOMER_CHECKOUT_*`, and credit applied from such a payment): the payment's key.
  - `customer_payment_source_kind` (string | null, optional): Customer Portal payment entries only: what the entry is, for example `funding` for the payment, the kind of change for an adjustment (such as `refund`), or `application` for credit applied from it.
  - `customer_payment_sources` (array of objects, optional): Customer Portal payment entries only: the Customer Portal payments the entry draws on, when it lists them; empty otherwise.
    - Each item:
      - `amount` (string | null, optional): A decimal string, such as `"25.00"`; parse it as a decimal.
      - `currency_iso` (string | null, optional)
      - `customer_payment_funding_id` (string | null, optional)
      - `funding_transaction_id` (string | null, optional)
  - `funding_payment_gateway` (string | null, optional): Customer Portal payment entries only: the payment's provider, as in `payment_gateway`.
  - `funding_transaction_id` (string | null, optional): Customer Portal payment entries only: the id of the payment's `CUSTOMER_CHECKOUT_FUNDING` entry.
  - `has_open_hold` (boolean, optional): Customer Portal payment entries only: true while the payment is held, for example by an open dispute, or when YoPrint could not read the payment.
  - `is_deletable` (boolean, optional)
  - `is_editable` (boolean, optional)
  - `is_external_cash_movement` (boolean, optional): Customer Portal payment entries only: true when money moved through the provider (the payment and its adjustments), false for credit moved inside YoPrint.
  - `order_id` (null, optional): Always null on customer credit entries, also for credit used on or refunded from a sales order. `credit_source` names the order where there is one.
  - `payment_gateway` (string | null, optional): The payment provider for entries that moved money through one: for a Customer Portal payment, `STRIPE`, `PAYPAL`, `SQUARE_V2`, `AUTHORIZE_NET` or `CHARGE_IT_PRO`. Null otherwise.
  - `payment_method_id` (string | null, optional)
  - `payment_notices` (array of objects, optional): Customer Portal payment entries only: why the payment needs attention, such as `dispute_open`, `dispute_under_review` or `payment_needs_attention`.
    - Each item:
      - `code` (string, optional)
      - `customer_payment_funding_id` (string | null, optional)
      - `next_action` (string | null, optional)
  - `provider_refund_reference` (string, optional): Only on a Customer Portal payment refund that has one: the provider's refund reference.
  - `recovery_kind` (string | null, optional): `CUSTOMER_CREDIT_RECOVERY` and `CUSTOMER_CREDIT_RESTORED` entries only: `credit_consumed` when unspent credit was taken back, `negative_credit` when spent credit was taken back and the balance went below zero. One of: `"credit_consumed"`, `"negative_credit"`.
  - `reference_description` (string | null, optional)
  - `reference_id` (string | null, optional): Your reference; on a Customer Portal payment adjustment, the payment provider's reference.
  - `refundable_amount` (integer | number | string, optional): How much of it can still be refunded; 0 for credit entries. Thousandths, an older encoding: `12500` is 12.50. Usually a whole number; an amount finer than a thousandth comes back as a number with a fraction (`1234.5` is 1.2345), or as a string (`"1234.5"`) when you send `X-Yoprint-Decimal-Format: exact-v1`. See [Money and quantities](/concepts/money-and-quantities/).
  - `related_transaction` (string | null, optional): The entry this one belongs to: for a refund, the payment; for `CUSTOMER_CREDIT_RECOVERY` and `CUSTOMER_CREDIT_RESTORED`, the refund; for a Customer Portal payment adjustment, its `CUSTOMER_CHECKOUT_FUNDING` entry. Null otherwise.
  - `restores_transaction_id` (string | null, optional): `CUSTOMER_CREDIT_RESTORED` only: the `CUSTOMER_CREDIT_RECOVERY` entry it gives back.
  - `reversal_transaction_id` (string | null, optional): `CUSTOMER_CREDIT_RESTORED` only: the entry that recorded the failed refund.
  - `token` (string | null, optional)
  - `user_id` (string | null, optional): Who made it.
  - `voided` (boolean, optional)
- `status` (integer, required)
- `success` (boolean, required)

Example response:

```json
{
  "data": {
    "action": "CUSTOMER_DEPOSIT",
    "amount": 50000,
    "credit_source": null,
    "customer_id": "V4keXwwxMQyXw7",
    "date": "2026-11-01T09:00:00+00:00",
    "direction": "INCREASE",
    "id": "mJ3uYS5OJQ9VEq",
    "is_deletable": true,
    "is_editable": false,
    "order_id": null,
    "payment_gateway": null,
    "payment_method_id": "6nz3Vu9sFR4dxM",
    "reference_description": null,
    "reference_id": "CHQ-1001",
    "refundable_amount": 0,
    "related_transaction": null,
    "subtype": "TRANSFER",
    "token": null,
    "type": "MANUAL",
    "user_id": "lOURnovd3hkIQI",
    "voided": false
  },
  "status": 200,
  "success": true
}
```

## Errors

- `401` The API key is missing or wrong (`unauthenticated`).
- `403` You are not allowed to do this. `api_access_not_in_plan`: your team's plan doesn't include API access (Pro and above, with an active subscription or trial), so every request answers this until the team upgrades. When your role lacks the permission the operation needs, the body is only `{"message": "Insufficient Permission"}`. Other refusals use the error envelope, with `unauthorized` or `user_is_not_authorized`.
  - When: Your role can't change this customer: it has no Manage Customers permission, or it manages only customers assigned to you and this one is not. This 403 has a short body, `{"message": "No Permission to update Customer"}`. Fix: Ask for Manage Customers "Manage All", or to be assigned to the customer.
- `404` Not found. `page_not_found`: the team slug is unknown, you are not a member of the team, or an id in the path is not one of this team's. `code: null`, with a message that starts "No query results for": there is no record with that id.
  - When: The customer is deleted, or not the team's. `error.code` is null and `error.message` names the record type. Fix: Restore a deleted customer first.
- `422` The request was refused and changed nothing. `validation_failed` lists what to fix in `error.fields`; other codes name a business rule, explained in `error.message`. A few checks answer with only `{"message": "..."}`. An operation that calls another service (a payment provider, a carrier, an accounting app) can answer `connect_timeout` ("Please retry again") when that service does not answer in time: the change may or may not have happened there, so read the record back before you retry.
  - When: Not enough available credit for the withdrawal (`error.code` `validation_error`, "Insufficient Customer Balance to perform such action"). Fix: Read the customer's `wallet_fund` and `held_credit` first.
  - When: `action` or `amount` is missing, `amount` is not a whole number of thousandths (such as `50000.5`; `error.fields.amount` says "The amount must be a whole number of thousandths of the currency unit, such as 12500 for 12.50."), or `payment_method_id` is not a payment method of the team. `error.code` is `validation_failed`. Fix: Fix each field named in `error.fields`; its keys are field paths such as `contact.0.phone`.
  - When: The customer comes from Shopify, or is a system customer (`error.code` `validation_error`, with the reason in `error.message`). Fix: Change Shopify customers in Shopify. System customers cannot be changed.

## Notes

- Not idempotent: each call adds a new entry. Do not retry blindly after a timeout; list the credit history first.

## Related

- [List a customer's credit history](https://developer.yoprint.com/reference/customer-credit/v1-customer-credit-index.md): `GET /v1/api/store/{team_slug}/customer/{hash_id}/credit`
- [Pay an order from the customer's credit](https://developer.yoprint.com/reference/payments/v2-sales-order-credit-pay-with-customer-credit.md): `POST /v2/api/store/{team_slug}/v2/sales_order/{hash_id}/credit/pay_with_customer_credit`
- [List payment methods](https://developer.yoprint.com/reference/payment-methods/v1-payment-method-index.md): `GET /v1/api/store/{team_slug}/setting/payment_method`
