Skip to main content

Overview

A deposit collects money from your customer. The customer pays a verified C2C member from their own mobile wallet, the member confirms receipt, and C2C credits your merchant wallet with the amount minus fees. The walletType you request is the payment method: JazzCash or Easypaisa, by account number, Till ID or QR code. The customer is only ever given a receiving account of exactly that method.

Flow diagram

Step by step

1. Create the order

Your backend calls Create Deposit Order with a signed request and an Idempotency-Key. Before creating anything, C2C checks:
  1. API key valid and active, otherwise 401
  2. Signature (the body’s signature field) valid, otherwise 401. Deposits are always signature-enforced.
  3. Request valid, otherwise 400
  4. Merchant account active and IP whitelist passed, otherwise 403
  5. Payment method (walletType) enabled for deposits on your account, otherwise 422
  6. merchantOrderRef not already used by an order that is in progress or completed, otherwise 409. See merchantOrderRef rules.
C2C then looks for an eligible member: online, with an approved receiving account of exactly the requested method, a limit covering the amount, and enough balance to back the deposit. No method falls back to another: JazzCash is never given a JazzCash Till ID or QR code, and never an Easypaisa account. See Exact matching.
  • Member found: the order is created as Queued (stage Assigned) with the member already assigned, and the member is notified in their app.
  • No member right now: the order is still accepted (200) as Awaiting (stage Awaiting), with the usual orderId, orderReference and paymentPageUrl. A member is assigned when the customer opens the payment page.
Your merchant fee is fixed when the order is accepted. It’s re-quoted only if the customer pays with a different method than you requested, and it’s capped at the deposit amount, so the credit to your wallet is never negative. Later fee-rule changes apply to new orders only.

2. Redirect the customer

Send the customer to paymentPageUrl right away. The link is valid for 15 minutes. See Hosted payment page.

3. Customer pays

The page opens on the method you requested. The customer sees where to pay, sends the money from their wallet app, and confirms on the page. What they submit depends on the method: The order moves Queued (or Awaiting) → AwaitingCustomerPayment → AwaitingMemberConfirmation. See Hosted payment page for each screen. For an Awaiting order, an online member with an account of the requested method is assigned as soon as the customer opens the page, and their account is shown. If none is online yet, the page shows “Finding an available agent…” and re-checks automatically every 10 seconds. The customer must not send money until an account number, Till ID or QR code is shown.

4. Member confirms

The member checks that the payment arrived:
  • Confirmed → Completed. Your wallet is credited amount − fee, and an order.completed webhook is sent.
  • Rejected, for example because no matching payment was found → Rejected, and an order.failed webhook is sent.

5. Fulfil

Fulfil the purchase only when the status is Completed. If you set successUrl / failureUrl, the payment page sends the customer back to you with the outcome appended; still confirm the status server-side before fulfilling. See Returning the customer.

Status lifecycle

Example: complete deposit integration

Best practices

  • Store orderId and your Idempotency-Key with your order before you redirect.
  • Use webhooks and reconcile: every final outcome sends a webhook, but ManualReview doesn’t until it’s resolved, and deliveries can fail.
  • Don’t fulfil early: Awaiting, Queued, AwaitingCustomerPayment and AwaitingMemberConfirmation are all in-progress states.
  • Redirect Awaiting orders as usual. The payment page assigns a member when the customer opens it.
  • Treat ManualReview as pending. The customer may have paid, so don’t ask them to pay again until C2C resolves it.
  • One live order per merchantOrderRef. To let the customer try again after a failed order, create a new order (new Idempotency-Key); you can reuse the same merchantOrderRef.