purserDOCS

Refunds

purser never touches money: it calls your own endpoint, your system sets the amount, the AI offers a refund only when the rules allow it, and refunds within your limits run automatically while the rest wait for approval.

purser never touches money

purser does not handle money and stores no payment credentials. To refund, it calls an HTTPS endpoint on your own server, and your system carries out the refund. Every request is signed and carries an idempotency key, so a retry never refunds twice.

This is meant for shops that run their own store software. Refunds and other actions need the Growth plan or higher. On a plan without them, your settings are kept but refund actions are switched off.

For the request format, signatures and responses, see Actions API.

Setting it up

In Settings (设置) → Refunds (退款) (only owners and admins can change it):

  1. Refund endpoint URL (退款接口地址): an https address on your server.
  2. Create secret (生成密钥): shown only once; put it in your system's environment variables. You can later Rotate secret (换新密钥); the old one stops working immediately, so update your system at the same time.
  3. Test connection (测试连接): purser sends a signed test request and shows whether the connection works, or why not.
  4. How to refund (怎么退):
    • Refund directly (直接退款): your endpoint refunds when it receives the request and returns the result.
    • Submit a refund request only (只提交退款申请): your endpoint only records the request; your team or ERP handles it and reports the result through the status API.
  5. Limits that need no approval (不用人批准的额度): currency, maximum per refund, maximum per day. The defaults are USD, 100 per refund and 500 per day.
  6. Turn on Enabled (启用). You cannot enable it before setting the endpoint URL and creating a secret. While it is off, the AI does not offer refunds and your team cannot start them from the inbox.

Who can start a refund

Your team

In the inbox, anyone on the team can click Refund (退款) on any order: choose a reason (damaged or not as described, not received, return, other), optionally add a note (it is sent to your system), click Preview amount (先看金额), and after seeing the amount your system calculated, click Confirm refund (确认退款). The person who starts it is the approver, and it runs immediately.

If the amount your system calculates changes between the preview and the confirmation, the confirmation is refused and you are asked to confirm the new amount.

The AI

For now the AI offers a refund in one situation only: a customer says in the chat that an item arrived damaged or wrong and uploads photos, the photo evidence is clean, and the autonomy level for damaged or wrong items (破损/错发) is R3 or R4 (see How the AI answers). The claim is then approved automatically and the AI offers the customer a refund.

Before the AI offers a refund, all of the following must hold. These are fixed rules; no model decides them:

  • The customer is signed in and the order is theirs.
  • The order has not been refunded or cancelled.
  • Time limit: for damaged or not-as-described items, the longer of the return window and the warranty; for a plain return, the return window only. Counted from delivery, or from the order date when there is no delivery record. Both come from the policy numbers (政策数字) in your knowledge base; if neither is set, a person decides.
  • For "not received" and any other reason, the AI never offers a refund; a person handles it.
  • No other refund is in progress for the same order (one at a time per order, including refunds your team starts).
  • The order has not already been refunded through purser (your team can still refund again, for example a partial top-up).
  • Your endpoint's refund.preview returned an amount and did not refuse.

The amount always comes from your refund.preview, never from a model.

The customer confirms

The customer sees the amount in the chat window and taps "Yes, refund me" or "No thanks". If they do not answer within 24 hours, the offer expires. Everything the customer is told about a refund comes from fixed templates (12 languages), not from a model.

Automatic, or waiting for approval

After the customer confirms, the refund runs automatically only if all of these hold:

  • Refunds are enabled.
  • Automatic refunds are not frozen.
  • The autonomy level for this question type (damaged or wrong items) is R4.
  • The currency matches the limit currency (refunds in any other currency always need approval).
  • The amount is within the maximum per refund.
  • Today's automatic refunds (UTC day) plus this one stay within the maximum per day.

If any of these fails, the refund goes to Awaiting your approval (等你批准) on the Refunds (退款) page in the sidebar, with the reasons listed (for example, that the level is R2 and automatic refunds need R4, or that the per-refund limit is exceeded). Anyone on the team can click Approve and refund (批准并退款) to call your endpoint straight away, or Reject (拒绝) with a reason (the customer does not see it; it is kept in the audit trail).

Automatic freeze

After every automatic refund, purser checks whether today's automatic refund total is more than 3 times the median daily automatic refund total of the previous 7 days. If it is, automatic refunds are frozen immediately and every refund a customer confirms needs a person's approval.

  • Only the limit currency is counted, and days are UTC days.
  • If fewer than 4 of the previous 7 days had automatic refunds (so the median is 0), the freeze cannot trigger; the maximum per day is the safeguard then.
  • While frozen, the reason is shown at the top of the Refunds page and of Settings → Refunds. An owner or admin lifts it with Resume automatic refunds (恢复自动退款) in settings.

Idempotency and retries

  • Every refund has a unique idempotency key, sent in both a header and the request body.
  • When your endpoint gives no clear answer (an error, a 10-second timeout, a redirect, or a response that is not the agreed JSON), purser retries with backoff using the same idempotency key, up to 5 retries. If you deduplicate on that key, nothing is refunded twice. purser does not follow redirects.
  • When your endpoint clearly refuses (a 4xx with "ok": false, including a 401 for a bad signature), the refund is marked failed and not retried.
  • If every retry fails, the refund is marked failed with the reason in its record, for a person to deal with.
  • In "submit a refund request only" mode, or when your endpoint answers that the refund is pending, the status is Merchant processing (商家处理中) until you report the result through the status API. The customer gets the result in the original conversation.

Audit trail

Recent refunds (最近的退款) on the Refunds page lists every refund the AI offered or your team started. Expand History (经过) to see the full record: who proposed it, on what basis (for example, days since delivery and the time limit that applied), whether the customer confirmed, who approved or rejected it, and every response from your endpoint.

Refund statuses as shown in the console:

StatusMeaning
等顾客确认 (awaiting customer)The AI has shown the amount and is waiting for the customer to confirm
等人批准 (awaiting approval)The customer confirmed, but the conditions for automatic execution are not met
正在退款 (refunding)Your endpoint is being called
商家处理中 (merchant processing)Your system accepted it; waiting for the result
已退款 (refunded)Done
失败 (failed)Your endpoint refused, or every retry failed
顾客不需要 (declined)The customer tapped "No thanks"
已拒绝 (rejected)Someone on your team rejected it
已取消 (cancelled)Cancelled
顾客没回应,已过期 (expired)The customer did not confirm within 24 hours

In test chat you can confirm a refund as the customer, but your refund endpoint is never called.

On this page