Social Pay vs pocket transfer
Two different rails. Do not treat Social Pay as silent institutional treasury.
OpenAPI tag: Transfers. Use this page to pay another Bit2Me user. To send crypto to an external blockchain address, use address-book withdrawals instead (destination wallet verified the first time only; no separate Travel Rule call on that path).
Choose the rail
| Outcome | Rail | How you identify the destination |
|---|---|---|
| Pay an existing Bit2Me user | Social Pay (Transfers tag) | email, phone, or alias |
| Move between two pockets you already hold | Pocket transfer | destination.pocket (UUID) |
| USDC (or other crypto) to an external wallet | Address book or Wallet legacy | Blockchain address + network |
Local-currency last mile (off-ramp to fiat in the recipient’s country) is only available in Argentina, and only when the recipient is a Bit2Me user on this rail. Do not implement other country cash-outs from this API.
There is no published “lookup user before you debit” endpoint. Identify the recipient with email, phone, or alias on create. Treat 412 / 403 on Transfers as “user not valid / forbidden” per OpenAPI — do not invent a resolve-by-userId call.
There is no published invite for someone who does not have a Bit2Me account. Social Pay can sit in escrow until the payee claims (or auto-claim / expiry refund). That is not an onboarding API.
Social Pay (Bit2Me user)
Create via Wallet proforma operation: social-payment plus destination.email, phone, or alias, then POST /v1/wallet/transaction — or POST /v1/social-pay/order (same Transfers family).
POST /v1/social-pay/order body (CreatePayOrderDto):
| Field | Required | Notes |
|---|---|---|
pocketId | Yes | Source pocket |
type | Yes | Pay order type (OpenAPI PayOrderType) |
amount, currency | Yes | Decimal strings |
email / phone / alias | One of | How you address the Bit2Me user |
note | No |
A successful create is a Pay order (orderId, status: pending, expiryDate, walletMovementId) — not an instant credit to the payee’s pocket.
List pending: GET /v1/social-pay/order.
Claim (payee, chosen pocket):
POST /v1/social-pay/order/claimBody is an array of objects with orderId and pocketId. Destination pocket cannot be selected at create — only at claim (or via auto-claim to the first suitable pocket).
WebSocket types: social.payment.pending, social.payment.success, social.payment.expiration.
Pocket transfer (your pockets)
When both pocket UUIDs are known (parent treasury or two pockets on the same account), Wallet proforma with destination.pocket is a Wallet movement. It does not go through Pay escrow. Confirm parent ↔ subaccount in your environment before you promise both directions.
On-chain (not this tag)
External USDC (or other assets) leaves Bit2Me on the withdrawal APIs:
- Verify the destination wallet the first time (address book + 2FA). Later sends to the same
addressBookIdskip a new confirm. - Address book carries the Travel Rule fields (
walletType,walletOwnership,exchangeName) on the entry, so it has notravel-rule-ordercall. On Wallet legacy, submit Travel Rule with the operation id only when the operation returnspending_user_information.
What not to invent
- A lookup API that returns
userIdfrom email - Last-mile rails outside Argentina
- A documented switch to disable claim emails
- Treating Social Pay as
destination.pocket(different rail)
Travel Rule
Wallet legacy only: confirm the proforma, then POST /v2/blockchain-manager/travel-rule-order with the operation id.
Create subaccount POST
Creates a subaccount linked to the authenticated main account. The subaccount receives its own `userId` and can operate independently within the scope granted by the main account.