Payments API
REST endpoints for payments in SKUFlow: 7 operations with parameters, request and response fields, permissions and curl examples.
Base URL: https://app.skuflow.ai/api. Every call needs Authorization: Bearer skf_… (Authentication); {organizationId} ($ORGANIZATION_ID in the examples) is your business's id.
| Operation | Endpoint | Risk |
|---|---|---|
| List payments with totals | GET /organizations/{organizationId}/payments | read |
| Export payments as CSV | GET /organizations/{organizationId}/payments/export | read |
| Get a payment with its refunds | GET /organizations/{organizationId}/payments/{paymentId} | read |
| Record a payment on an invoice (moves money) | POST /organizations/{organizationId}/invoices/{invoiceId}/payments | sensitive |
| A quote's deposit: requested, collected, outstanding | GET /organizations/{organizationId}/quotes/{quoteId}/deposits | read |
| Record a deposit on an approved quote (moves money) | POST /organizations/{organizationId}/quotes/{quoteId}/deposits | sensitive |
| Refund a payment (moves money back) | POST /organizations/{organizationId}/payments/{paymentId}/refunds | sensitive |
List payments with totals
GET /organizations/{organizationId}/payments
Payments newest first (by paid date), filtered by method, processor (MANUAL or STRIPE), status, date range, customer, invoice or quote, with totals over every match (not only the page): amountCents, tipCents, refundedCents of received payments, collectedCents (amounts net of refunds, tips excluded: revenue, gross of fees), netTipCents, netCents = amount + tips − refunds, and feesCents (online-payment fees the business paid: Stripe's processing fees plus any SKUFlow fee). Online payments show PENDING until Stripe confirms them and FAILED when declined or abandoned. Read-only.
| Permission | payments.read (Owner, Admin, Staff) |
| Risk | read, OAuth scope skuflow.read. Read: reads only. |
| MCP tool | payments_list (toolset invoices, in the default set) |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
query | query | string | No | Matches PAY-n, the reference, the customer's name or the invoice number. Up to 200 characters. |
method | query | enum | No | How the customer paid: CASH, CHECK, CARD (taken on the business's own terminal), BANK_TRANSFER or OTHER. One of CASH, CHECK, CARD, BANK_TRANSFER, OTHER. |
processor | query | enum | No | Manual: recorded by staff. STRIPE: paid online through Stripe (Checkout or autopay). One of MANUAL, STRIPE. |
status | query | enum | No | SUCCEEDED (counts), PENDING / FAILED (online payments not settled; count for nothing), PARTIALLY_REFUNDED, REFUNDED. One of SUCCEEDED, PENDING, FAILED, REFUNDED, PARTIALLY_REFUNDED. |
from | query | string | No | Paid on or after (YYYY-MM-DD). |
to | query | string | No | Paid on or before (YYYY-MM-DD). |
customerId | query | string | No | |
invoiceId | query | string | No | |
quoteId | query | string | No | Deposits taken on this quote. |
limit | query | integer | No | Page size, 1–200. Default 50. |
offset | query | integer | No | Rows to skip; the answer's total counts every match. Default 0. |
Example
curl "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/payments" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
items | array of object | |
items[].id | string | |
items[].identifier | string | PAY-n, unique per organization. |
items[].customerId | string | |
items[].customer | object | |
items[].customer.id | string | |
items[].customer.name | string | |
items[].invoiceId | string or null | |
items[].invoice | object or null | |
items[].invoice.id | string | |
items[].invoice.identifier | string | |
items[].invoice.status | string | |
items[].quoteId | string or null | Set when the payment was a deposit on a quote. |
items[].quote | object or null | |
items[].quote.id | string | |
items[].quote.identifier | string | |
items[].quote.title | string | |
items[].amountCents | integer | |
items[].tipCents | integer | |
items[].refundedCents | integer | Succeeded refunds so far. |
items[].method | enum | How the customer paid: CASH, CHECK, CARD (taken on the business's own terminal), BANK_TRANSFER or OTHER. One of CASH, CHECK, CARD, BANK_TRANSFER, OTHER. |
items[].paidOn | string | |
items[].reference | string or null | |
items[].note | string or null | |
items[].processor | enum | Manual: recorded by staff. STRIPE: paid online through Stripe (Checkout or autopay). One of MANUAL, STRIPE. |
items[].processorPaymentId | string or null | Stripe PaymentIntent (pi_…). |
items[].processorChargeId | string or null | |
items[].processorAccountId | string or null | The connected Stripe account it was paid into. |
items[].processorChargeType | enum or null | How an online payment was charged: DIRECT on the business's own Stripe account (every payment now), DESTINATION for older payments made on the platform. One of DIRECT, DESTINATION. |
items[].processorSessionId | string or null | The Stripe Checkout Session (cs_…). |
items[].processorFeeCents | integer or null | Stripe's processing fee, billed by Stripe to the business (older DESTINATION payments: paid by the platform). Null until Stripe reports it. |
items[].platformFeeCents | integer or null | SKUFlow's fee on this online payment: 0 or null (SKUFlow takes no fee). |
items[].feesCents | integer | Fees the business paid on this payment: Stripe's processing fee (direct charges) plus any SKUFlow fee. |
items[].netCents | integer | What reaches the business: amount + tip − feesCents (before refunds). |
items[].paymentMethodType | string or null | card | us_bank_account for online payments. |
items[].cardBrand | string or null | |
items[].cardLast4 | string or null | |
items[].methodLabel | string or null | Visa •••• 4242, Bank •••• 6789 (online payments). |
items[].onlineChannel | enum or null | Where an online payment was started. One of PORTAL, INVOICE_LINK, QUOTE_PAGE, STAFF, AUTOPAY, STORE. |
items[].disputed | boolean | The customer's bank opened a dispute (chargeback). |
items[].disputeStatus | string or null | |
items[].failureReason | string or null | |
items[].status | enum | SUCCEEDED (counts), PENDING / FAILED (online payments not settled; count for nothing), PARTIALLY_REFUNDED, REFUNDED. One of SUCCEEDED, PENDING, FAILED, REFUNDED, PARTIALLY_REFUNDED. |
items[].recordedBy | object or null | |
items[].recordedBy.id | string | |
items[].recordedBy.name | string or null | |
items[].refunds | array of object | |
items[].refunds[].id | string | |
items[].refunds[].paymentId | string | |
items[].refunds[].amountCents | integer | |
items[].refunds[].reason | string or null | |
items[].refunds[].refundedOn | string | |
items[].refunds[].processor | enum | One of MANUAL, STRIPE. |
items[].refunds[].processorRefundId | string or null | Stripe's refund id (re_…) for online refunds. |
items[].refunds[].status | enum | Online refunds are PENDING until Stripe confirms them; only SUCCEEDED counts. One of SUCCEEDED, PENDING, FAILED. |
items[].refunds[].failureReason | string or null | |
items[].refunds[].recordedBy | object or null | |
items[].refunds[].createdAt | string (date-time) | |
items[].createdAt | string (date-time) | |
items[].updatedAt | string (date-time) | |
total | integer | |
totals | object | |
totals.count | integer | |
totals.amountCents | integer | |
totals.tipCents | integer | |
totals.refundedCents | integer | |
totals.collectedCents | integer | Amounts received less refunds, tips excluded: what counts as revenue. |
totals.netTipCents | integer | Tips received less refunds that reached them. |
totals.netCents | integer | |
totals.feesCents | integer | Online-payment fees the business paid: Stripe's processing fees (billed by Stripe) plus any SKUFlow fee. |
Export payments as CSV
GET /organizations/{organizationId}/payments/export
The payments list as a CSV file (the Payments page's Export CSV), with the same filters as GET /payments and every matching row (up to 10,000): payment, paid on, customer, invoice, quote, method, processor, card, reference, status, amount, tip, refunded, fees, net, recorded by, note. Amounts in dollars. Read-only.
| Permission | payments.read (Owner, Admin, Staff) |
| Risk | read, OAuth scope skuflow.read. Read: reads only. |
| MCP tool | payments_export (toolset invoices) |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
query | query | string | No | Matches PAY-n, the reference, the customer's name or the invoice number. Up to 200 characters. |
method | query | enum | No | How the customer paid: CASH, CHECK, CARD (taken on the business's own terminal), BANK_TRANSFER or OTHER. One of CASH, CHECK, CARD, BANK_TRANSFER, OTHER. |
processor | query | enum | No | Manual: recorded by staff. STRIPE: paid online through Stripe (Checkout or autopay). One of MANUAL, STRIPE. |
status | query | enum | No | SUCCEEDED (counts), PENDING / FAILED (online payments not settled; count for nothing), PARTIALLY_REFUNDED, REFUNDED. One of SUCCEEDED, PENDING, FAILED, REFUNDED, PARTIALLY_REFUNDED. |
from | query | string | No | Paid on or after (YYYY-MM-DD). |
to | query | string | No | Paid on or before (YYYY-MM-DD). |
customerId | query | string | No | |
invoiceId | query | string | No | |
quoteId | query | string | No |
Example
curl "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/payments/export" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
fileName | string | |
csv | string | UTF-8 CSV with a header row. |
count | integer | Payments in the file. |
Get a payment with its refunds
GET /organizations/{organizationId}/payments/{paymentId}
One payment, its invoice or quote, who recorded it, and every refund on it. Read-only.
| Permission | payments.read (Owner, Admin, Staff) |
| Risk | read, OAuth scope skuflow.read. Read: reads only. |
| MCP tool | payments_get (toolset invoices) |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
paymentId | path | string | Yes |
Example
curl "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/payments/{paymentId}" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
id | string | |
identifier | string | PAY-n, unique per organization. |
customerId | string | |
customer | object | |
customer.id | string | |
customer.name | string | |
invoiceId | string or null | |
invoice | object or null | |
invoice.id | string | |
invoice.identifier | string | |
invoice.status | string | |
quoteId | string or null | Set when the payment was a deposit on a quote. |
quote | object or null | |
quote.id | string | |
quote.identifier | string | |
quote.title | string | |
amountCents | integer | |
tipCents | integer | |
refundedCents | integer | Succeeded refunds so far. |
method | enum | How the customer paid: CASH, CHECK, CARD (taken on the business's own terminal), BANK_TRANSFER or OTHER. One of CASH, CHECK, CARD, BANK_TRANSFER, OTHER. |
paidOn | string | |
reference | string or null | |
note | string or null | |
processor | enum | Manual: recorded by staff. STRIPE: paid online through Stripe (Checkout or autopay). One of MANUAL, STRIPE. |
processorPaymentId | string or null | Stripe PaymentIntent (pi_…). |
processorChargeId | string or null | |
processorAccountId | string or null | The connected Stripe account it was paid into. |
processorChargeType | enum or null | How an online payment was charged: DIRECT on the business's own Stripe account (every payment now), DESTINATION for older payments made on the platform. One of DIRECT, DESTINATION. |
processorSessionId | string or null | The Stripe Checkout Session (cs_…). |
processorFeeCents | integer or null | Stripe's processing fee, billed by Stripe to the business (older DESTINATION payments: paid by the platform). Null until Stripe reports it. |
platformFeeCents | integer or null | SKUFlow's fee on this online payment: 0 or null (SKUFlow takes no fee). |
feesCents | integer | Fees the business paid on this payment: Stripe's processing fee (direct charges) plus any SKUFlow fee. |
netCents | integer | What reaches the business: amount + tip − feesCents (before refunds). |
paymentMethodType | string or null | card | us_bank_account for online payments. |
cardBrand | string or null | |
cardLast4 | string or null | |
methodLabel | string or null | Visa •••• 4242, Bank •••• 6789 (online payments). |
onlineChannel | enum or null | Where an online payment was started. One of PORTAL, INVOICE_LINK, QUOTE_PAGE, STAFF, AUTOPAY, STORE. |
disputed | boolean | The customer's bank opened a dispute (chargeback). |
disputeStatus | string or null | |
failureReason | string or null | |
status | enum | SUCCEEDED (counts), PENDING / FAILED (online payments not settled; count for nothing), PARTIALLY_REFUNDED, REFUNDED. One of SUCCEEDED, PENDING, FAILED, REFUNDED, PARTIALLY_REFUNDED. |
recordedBy | object or null | |
recordedBy.id | string | |
recordedBy.name | string or null | |
refunds | array of object | |
refunds[].id | string | |
refunds[].paymentId | string | |
refunds[].amountCents | integer | |
refunds[].reason | string or null | |
refunds[].refundedOn | string | |
refunds[].processor | enum | One of MANUAL, STRIPE. |
refunds[].processorRefundId | string or null | Stripe's refund id (re_…) for online refunds. |
refunds[].status | enum | Online refunds are PENDING until Stripe confirms them; only SUCCEEDED counts. One of SUCCEEDED, PENDING, FAILED. |
refunds[].failureReason | string or null | |
refunds[].recordedBy | object or null | |
refunds[].recordedBy.id | string | |
refunds[].recordedBy.name | string or null | |
refunds[].createdAt | string (date-time) | |
createdAt | string (date-time) | |
updatedAt | string (date-time) |
Record a payment on an invoice (moves money)
POST /organizations/{organizationId}/invoices/{invoiceId}/payments
Money: records money the business received for this invoice (processor MANUAL; nothing is charged). amountCents must be above 0 and at most the balance due: overpayment is refused (400); add extra as tipCents. A cancelled invoice cannot take payments. When the balance reaches 0 the invoice becomes PAID with that day as its paid date; a partial payment leaves its status and reads as partially paid. Needs payments.record (owners, admins, staff). The business's "Payment receipt" automation (when on) emails a receipt; notifyCustomer: false sends nothing for this payment. Get the invoice and its balanceDueCents with GET /invoices/{invoiceId} first. Returns the payment.
| Permission | payments.record (Owner, Admin, Staff) |
| Risk | sensitive, OAuth scope skuflow.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access. |
| MCP tool | payments_record (toolset invoices, in the default set) |
| Approval | Over MCP, this tool asks for your OK first (in the AI app when it supports it, otherwise in SKUFlow). See Approvals. |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
invoiceId | path | string | Yes |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
amountCents | integer | Yes | Amount towards the balance, in integer cents. Must not exceed the balance due (overpayment is refused). 1–100000000. |
tipCents | integer | No | Tip on top of the amount, in cents. Never reduces the balance; reported apart from revenue. 0–100000000. |
method | enum | Yes | How the customer paid: CASH, CHECK, CARD (taken on the business's own terminal), BANK_TRANSFER or OTHER. One of CASH, CHECK, CARD, BANK_TRANSFER, OTHER. |
paidOn | empty string or string or null | No | The day the money was received (YYYY-MM-DD); defaults to today. |
reference | string or null | No | Check number, card last four or transfer reference, if any. Up to 200 characters. |
note | string or null | No | Internal note; never shown to the customer. Up to 5000 characters. |
today | string | No | The business's today (YYYY-MM-DD) for defaults and due-date checks; defaults to today in UTC. |
notifyCustomer | boolean | No | Default true: the business's automations (the payment receipt) run. False: nothing is sent to the customer for this payment. |
Example
curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/invoices/{invoiceId}/payments" \
-H "Authorization: Bearer $SKUFLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"amountCents":12500,"method":"CASH"}'Response
201: the answer's fields
| Field | Type | Description |
|---|---|---|
id | string | |
identifier | string | PAY-n, unique per organization. |
customerId | string | |
customer | object | |
customer.id | string | |
customer.name | string | |
invoiceId | string or null | |
invoice | object or null | |
invoice.id | string | |
invoice.identifier | string | |
invoice.status | string | |
quoteId | string or null | Set when the payment was a deposit on a quote. |
quote | object or null | |
quote.id | string | |
quote.identifier | string | |
quote.title | string | |
amountCents | integer | |
tipCents | integer | |
refundedCents | integer | Succeeded refunds so far. |
method | enum | How the customer paid: CASH, CHECK, CARD (taken on the business's own terminal), BANK_TRANSFER or OTHER. One of CASH, CHECK, CARD, BANK_TRANSFER, OTHER. |
paidOn | string | |
reference | string or null | |
note | string or null | |
processor | enum | Manual: recorded by staff. STRIPE: paid online through Stripe (Checkout or autopay). One of MANUAL, STRIPE. |
processorPaymentId | string or null | Stripe PaymentIntent (pi_…). |
processorChargeId | string or null | |
processorAccountId | string or null | The connected Stripe account it was paid into. |
processorChargeType | enum or null | How an online payment was charged: DIRECT on the business's own Stripe account (every payment now), DESTINATION for older payments made on the platform. One of DIRECT, DESTINATION. |
processorSessionId | string or null | The Stripe Checkout Session (cs_…). |
processorFeeCents | integer or null | Stripe's processing fee, billed by Stripe to the business (older DESTINATION payments: paid by the platform). Null until Stripe reports it. |
platformFeeCents | integer or null | SKUFlow's fee on this online payment: 0 or null (SKUFlow takes no fee). |
feesCents | integer | Fees the business paid on this payment: Stripe's processing fee (direct charges) plus any SKUFlow fee. |
netCents | integer | What reaches the business: amount + tip − feesCents (before refunds). |
paymentMethodType | string or null | card | us_bank_account for online payments. |
cardBrand | string or null | |
cardLast4 | string or null | |
methodLabel | string or null | Visa •••• 4242, Bank •••• 6789 (online payments). |
onlineChannel | enum or null | Where an online payment was started. One of PORTAL, INVOICE_LINK, QUOTE_PAGE, STAFF, AUTOPAY, STORE. |
disputed | boolean | The customer's bank opened a dispute (chargeback). |
disputeStatus | string or null | |
failureReason | string or null | |
status | enum | SUCCEEDED (counts), PENDING / FAILED (online payments not settled; count for nothing), PARTIALLY_REFUNDED, REFUNDED. One of SUCCEEDED, PENDING, FAILED, REFUNDED, PARTIALLY_REFUNDED. |
recordedBy | object or null | |
recordedBy.id | string | |
recordedBy.name | string or null | |
refunds | array of object | |
refunds[].id | string | |
refunds[].paymentId | string | |
refunds[].amountCents | integer | |
refunds[].reason | string or null | |
refunds[].refundedOn | string | |
refunds[].processor | enum | One of MANUAL, STRIPE. |
refunds[].processorRefundId | string or null | Stripe's refund id (re_…) for online refunds. |
refunds[].status | enum | Online refunds are PENDING until Stripe confirms them; only SUCCEEDED counts. One of SUCCEEDED, PENDING, FAILED. |
refunds[].failureReason | string or null | |
refunds[].recordedBy | object or null | |
refunds[].recordedBy.id | string | |
refunds[].recordedBy.name | string or null | |
refunds[].createdAt | string (date-time) | |
createdAt | string (date-time) | |
updatedAt | string (date-time) |
A quote's deposit: requested, collected, outstanding
GET /organizations/{organizationId}/quotes/{quoteId}/deposits
requestedCents is the deposit the approval asked for, collectedCents the deposits received net of refunds (applied to an invoice or not), outstandingCents what is left to collect, with the deposit payments. Read-only.
| Permission | payments.read (Owner, Admin, Staff) |
| Risk | read, OAuth scope skuflow.read. Read: reads only. |
| MCP tool | payments_deposits (toolset invoices) |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
quoteId | path | string | Yes |
Example
curl "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/quotes/{quoteId}/deposits" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
requestedCents | integer | |
collectedCents | integer | |
outstandingCents | integer | |
payments | array of object | |
payments[].id | string | |
payments[].identifier | string | PAY-n, unique per organization. |
payments[].customerId | string | |
payments[].customer | object | |
payments[].customer.id | string | |
payments[].customer.name | string | |
payments[].invoiceId | string or null | |
payments[].invoice | object or null | |
payments[].invoice.id | string | |
payments[].invoice.identifier | string | |
payments[].invoice.status | string | |
payments[].quoteId | string or null | Set when the payment was a deposit on a quote. |
payments[].quote | object or null | |
payments[].quote.id | string | |
payments[].quote.identifier | string | |
payments[].quote.title | string | |
payments[].amountCents | integer | |
payments[].tipCents | integer | |
payments[].refundedCents | integer | Succeeded refunds so far. |
payments[].method | enum | How the customer paid: CASH, CHECK, CARD (taken on the business's own terminal), BANK_TRANSFER or OTHER. One of CASH, CHECK, CARD, BANK_TRANSFER, OTHER. |
payments[].paidOn | string | |
payments[].reference | string or null | |
payments[].note | string or null | |
payments[].processor | enum | Manual: recorded by staff. STRIPE: paid online through Stripe (Checkout or autopay). One of MANUAL, STRIPE. |
payments[].processorPaymentId | string or null | Stripe PaymentIntent (pi_…). |
payments[].processorChargeId | string or null | |
payments[].processorAccountId | string or null | The connected Stripe account it was paid into. |
payments[].processorChargeType | enum or null | How an online payment was charged: DIRECT on the business's own Stripe account (every payment now), DESTINATION for older payments made on the platform. One of DIRECT, DESTINATION. |
payments[].processorSessionId | string or null | The Stripe Checkout Session (cs_…). |
payments[].processorFeeCents | integer or null | Stripe's processing fee, billed by Stripe to the business (older DESTINATION payments: paid by the platform). Null until Stripe reports it. |
payments[].platformFeeCents | integer or null | SKUFlow's fee on this online payment: 0 or null (SKUFlow takes no fee). |
payments[].feesCents | integer | Fees the business paid on this payment: Stripe's processing fee (direct charges) plus any SKUFlow fee. |
payments[].netCents | integer | What reaches the business: amount + tip − feesCents (before refunds). |
payments[].paymentMethodType | string or null | card | us_bank_account for online payments. |
payments[].cardBrand | string or null | |
payments[].cardLast4 | string or null | |
payments[].methodLabel | string or null | Visa •••• 4242, Bank •••• 6789 (online payments). |
payments[].onlineChannel | enum or null | Where an online payment was started. One of PORTAL, INVOICE_LINK, QUOTE_PAGE, STAFF, AUTOPAY, STORE. |
payments[].disputed | boolean | The customer's bank opened a dispute (chargeback). |
payments[].disputeStatus | string or null | |
payments[].failureReason | string or null | |
payments[].status | enum | SUCCEEDED (counts), PENDING / FAILED (online payments not settled; count for nothing), PARTIALLY_REFUNDED, REFUNDED. One of SUCCEEDED, PENDING, FAILED, REFUNDED, PARTIALLY_REFUNDED. |
payments[].recordedBy | object or null | |
payments[].recordedBy.id | string | |
payments[].recordedBy.name | string or null | |
payments[].refunds | array of object | |
payments[].refunds[].id | string | |
payments[].refunds[].paymentId | string | |
payments[].refunds[].amountCents | integer | |
payments[].refunds[].reason | string or null | |
payments[].refunds[].refundedOn | string | |
payments[].refunds[].processor | enum | One of MANUAL, STRIPE. |
payments[].refunds[].processorRefundId | string or null | Stripe's refund id (re_…) for online refunds. |
payments[].refunds[].status | enum | Online refunds are PENDING until Stripe confirms them; only SUCCEEDED counts. One of SUCCEEDED, PENDING, FAILED. |
payments[].refunds[].failureReason | string or null | |
payments[].refunds[].recordedBy | object or null | |
payments[].refunds[].createdAt | string (date-time) | |
payments[].createdAt | string (date-time) | |
payments[].updatedAt | string (date-time) |
Record a deposit on an approved quote (moves money)
POST /organizations/{organizationId}/quotes/{quoteId}/deposits
Money: records a deposit the customer paid on an APPROVED (or CONVERTED but not yet invoiced) quote. Deposits may add up to the approved total, never more. When the quote is invoiced (POST /quotes/{quoteId}/invoice) the deposits move onto that invoice and count as paid there. Returns the payment.
| Permission | payments.record (Owner, Admin, Staff) |
| Risk | sensitive, OAuth scope skuflow.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access. |
| MCP tool | payments_recordDeposit (toolset invoices) |
| Approval | Over MCP, this tool asks for your OK first (in the AI app when it supports it, otherwise in SKUFlow). See Approvals. |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
quoteId | path | string | Yes |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
amountCents | integer | Yes | Amount towards the balance, in integer cents. Must not exceed the balance due (overpayment is refused). 1–100000000. |
tipCents | integer | No | Tip on top of the amount, in cents. Never reduces the balance; reported apart from revenue. 0–100000000. |
method | enum | Yes | How the customer paid: CASH, CHECK, CARD (taken on the business's own terminal), BANK_TRANSFER or OTHER. One of CASH, CHECK, CARD, BANK_TRANSFER, OTHER. |
paidOn | empty string or string or null | No | The day the money was received (YYYY-MM-DD); defaults to today. |
reference | string or null | No | Check number, card last four or transfer reference, if any. Up to 200 characters. |
note | string or null | No | Internal note; never shown to the customer. Up to 5000 characters. |
today | string | No | The business's today (YYYY-MM-DD) for defaults and due-date checks; defaults to today in UTC. |
Example
curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/quotes/{quoteId}/deposits" \
-H "Authorization: Bearer $SKUFLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"amountCents":12500,"method":"CASH"}'Response
201: the answer's fields
| Field | Type | Description |
|---|---|---|
id | string | |
identifier | string | PAY-n, unique per organization. |
customerId | string | |
customer | object | |
customer.id | string | |
customer.name | string | |
invoiceId | string or null | |
invoice | object or null | |
invoice.id | string | |
invoice.identifier | string | |
invoice.status | string | |
quoteId | string or null | Set when the payment was a deposit on a quote. |
quote | object or null | |
quote.id | string | |
quote.identifier | string | |
quote.title | string | |
amountCents | integer | |
tipCents | integer | |
refundedCents | integer | Succeeded refunds so far. |
method | enum | How the customer paid: CASH, CHECK, CARD (taken on the business's own terminal), BANK_TRANSFER or OTHER. One of CASH, CHECK, CARD, BANK_TRANSFER, OTHER. |
paidOn | string | |
reference | string or null | |
note | string or null | |
processor | enum | Manual: recorded by staff. STRIPE: paid online through Stripe (Checkout or autopay). One of MANUAL, STRIPE. |
processorPaymentId | string or null | Stripe PaymentIntent (pi_…). |
processorChargeId | string or null | |
processorAccountId | string or null | The connected Stripe account it was paid into. |
processorChargeType | enum or null | How an online payment was charged: DIRECT on the business's own Stripe account (every payment now), DESTINATION for older payments made on the platform. One of DIRECT, DESTINATION. |
processorSessionId | string or null | The Stripe Checkout Session (cs_…). |
processorFeeCents | integer or null | Stripe's processing fee, billed by Stripe to the business (older DESTINATION payments: paid by the platform). Null until Stripe reports it. |
platformFeeCents | integer or null | SKUFlow's fee on this online payment: 0 or null (SKUFlow takes no fee). |
feesCents | integer | Fees the business paid on this payment: Stripe's processing fee (direct charges) plus any SKUFlow fee. |
netCents | integer | What reaches the business: amount + tip − feesCents (before refunds). |
paymentMethodType | string or null | card | us_bank_account for online payments. |
cardBrand | string or null | |
cardLast4 | string or null | |
methodLabel | string or null | Visa •••• 4242, Bank •••• 6789 (online payments). |
onlineChannel | enum or null | Where an online payment was started. One of PORTAL, INVOICE_LINK, QUOTE_PAGE, STAFF, AUTOPAY, STORE. |
disputed | boolean | The customer's bank opened a dispute (chargeback). |
disputeStatus | string or null | |
failureReason | string or null | |
status | enum | SUCCEEDED (counts), PENDING / FAILED (online payments not settled; count for nothing), PARTIALLY_REFUNDED, REFUNDED. One of SUCCEEDED, PENDING, FAILED, REFUNDED, PARTIALLY_REFUNDED. |
recordedBy | object or null | |
recordedBy.id | string | |
recordedBy.name | string or null | |
refunds | array of object | |
refunds[].id | string | |
refunds[].paymentId | string | |
refunds[].amountCents | integer | |
refunds[].reason | string or null | |
refunds[].refundedOn | string | |
refunds[].processor | enum | One of MANUAL, STRIPE. |
refunds[].processorRefundId | string or null | Stripe's refund id (re_…) for online refunds. |
refunds[].status | enum | Online refunds are PENDING until Stripe confirms them; only SUCCEEDED counts. One of SUCCEEDED, PENDING, FAILED. |
refunds[].failureReason | string or null | |
refunds[].recordedBy | object or null | |
refunds[].recordedBy.id | string | |
refunds[].recordedBy.name | string or null | |
refunds[].createdAt | string (date-time) | |
createdAt | string (date-time) | |
updatedAt | string (date-time) |
Refund a payment (moves money back)
POST /organizations/{organizationId}/payments/{paymentId}/refunds
DESTRUCTIVE / MONEY: gives money back to the customer on this payment. At most the payment's amount plus tip, less earlier refunds, including online refunds still pending (400 otherwise); pending or failed payments cannot be refunded. The refund comes off the invoice amount first, then the tip. MANUAL payments: recorded at once (nothing is sent anywhere). STRIPE payments: refunded through Stripe to the card or bank account (the transfer to the business is reversed and the platform fee returned in proportion); the refund is PENDING until Stripe's webhook confirms it, and only then does the invoice reopen (SENT, or OVERDUE past its due date). Needs payments.refund (owners and admins; 403 for others). Find the payment with GET /payments or GET /invoices/{invoiceId}. Returns the payment with its refunds.
| Permission | payments.refund (Owner, Admin) |
| Risk | sensitive, OAuth scope skuflow.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access. |
| MCP tool | payments_refund (toolset invoices) |
| Approval | Over MCP, this tool always waits for your approval in SKUFlow. See Approvals. |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
paymentId | path | string | Yes |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
amountCents | integer | Yes | Amount to give back, in cents. 1–100000000. |
reason | string or null | No | Why, for the record (internal). Up to 2000 characters. |
refundedOn | empty string or string or null | No | The day the money went back (YYYY-MM-DD); defaults to today. |
today | string | No | The business's today (YYYY-MM-DD) for defaults and due-date checks; defaults to today in UTC. |
Example
curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/payments/{paymentId}/refunds" \
-H "Authorization: Bearer $SKUFLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"amountCents":12500}'Response
201: the answer's fields
| Field | Type | Description |
|---|---|---|
id | string | |
identifier | string | PAY-n, unique per organization. |
customerId | string | |
customer | object | |
customer.id | string | |
customer.name | string | |
invoiceId | string or null | |
invoice | object or null | |
invoice.id | string | |
invoice.identifier | string | |
invoice.status | string | |
quoteId | string or null | Set when the payment was a deposit on a quote. |
quote | object or null | |
quote.id | string | |
quote.identifier | string | |
quote.title | string | |
amountCents | integer | |
tipCents | integer | |
refundedCents | integer | Succeeded refunds so far. |
method | enum | How the customer paid: CASH, CHECK, CARD (taken on the business's own terminal), BANK_TRANSFER or OTHER. One of CASH, CHECK, CARD, BANK_TRANSFER, OTHER. |
paidOn | string | |
reference | string or null | |
note | string or null | |
processor | enum | Manual: recorded by staff. STRIPE: paid online through Stripe (Checkout or autopay). One of MANUAL, STRIPE. |
processorPaymentId | string or null | Stripe PaymentIntent (pi_…). |
processorChargeId | string or null | |
processorAccountId | string or null | The connected Stripe account it was paid into. |
processorChargeType | enum or null | How an online payment was charged: DIRECT on the business's own Stripe account (every payment now), DESTINATION for older payments made on the platform. One of DIRECT, DESTINATION. |
processorSessionId | string or null | The Stripe Checkout Session (cs_…). |
processorFeeCents | integer or null | Stripe's processing fee, billed by Stripe to the business (older DESTINATION payments: paid by the platform). Null until Stripe reports it. |
platformFeeCents | integer or null | SKUFlow's fee on this online payment: 0 or null (SKUFlow takes no fee). |
feesCents | integer | Fees the business paid on this payment: Stripe's processing fee (direct charges) plus any SKUFlow fee. |
netCents | integer | What reaches the business: amount + tip − feesCents (before refunds). |
paymentMethodType | string or null | card | us_bank_account for online payments. |
cardBrand | string or null | |
cardLast4 | string or null | |
methodLabel | string or null | Visa •••• 4242, Bank •••• 6789 (online payments). |
onlineChannel | enum or null | Where an online payment was started. One of PORTAL, INVOICE_LINK, QUOTE_PAGE, STAFF, AUTOPAY, STORE. |
disputed | boolean | The customer's bank opened a dispute (chargeback). |
disputeStatus | string or null | |
failureReason | string or null | |
status | enum | SUCCEEDED (counts), PENDING / FAILED (online payments not settled; count for nothing), PARTIALLY_REFUNDED, REFUNDED. One of SUCCEEDED, PENDING, FAILED, REFUNDED, PARTIALLY_REFUNDED. |
recordedBy | object or null | |
recordedBy.id | string | |
recordedBy.name | string or null | |
refunds | array of object | |
refunds[].id | string | |
refunds[].paymentId | string | |
refunds[].amountCents | integer | |
refunds[].reason | string or null | |
refunds[].refundedOn | string | |
refunds[].processor | enum | One of MANUAL, STRIPE. |
refunds[].processorRefundId | string or null | Stripe's refund id (re_…) for online refunds. |
refunds[].status | enum | Online refunds are PENDING until Stripe confirms them; only SUCCEEDED counts. One of SUCCEEDED, PENDING, FAILED. |
refunds[].failureReason | string or null | |
refunds[].recordedBy | object or null | |
refunds[].recordedBy.id | string | |
refunds[].recordedBy.name | string or null | |
refunds[].createdAt | string (date-time) | |
createdAt | string (date-time) | |
updatedAt | string (date-time) |