<!-- x-generated: Generated by the Hyperscale artifact pipeline; do not edit by hand -->

# Digital Savings Circles

> The frozen Digital Savings Circles Product Build, version 1.

- Composition id: `digital_savings_circles`
- Version: 1
- Digest: `d7355a08a1cb6992ad0182727a462586c86b0fe6961ad0d4931445beae475c67`
- Currencies: `SAR`
- Webhook events: 25

## Instruments

| Instrument | Title | States | Actions |
| --- | --- | --- | --- |
| [`circle_membership`](../instruments/circle_membership.md) | Circle membership | 4 | create |
| [`savings_circle`](../instruments/savings_circle.md) | Savings circle | 4 | close, create |
| [`wallet`](../instruments/wallet.md) | Wallet | 4 | create |
| [`wallet_spend`](../instruments/wallet_spend.md) | Wallet spend | 3 | create |

## Journeys

### Run an active wallet cycle

- Journey id: `wallet_active_cycle`
- Steps: 9

1. `sandbox_customer_onboard`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/sandbox/customer-onboarding`, scopes customer:write, idempotency required, receipt yes
   - Body: displayName, productId
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: none
2. `sandbox_customer_access_activate`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/sandbox/customer-access/{customerAccessId}/activate`, scopes customer:write, idempotency required, receipt yes
   - Body: none
   - Path: customerAccessId
   - Query: none
   - Expect: none
   - Bindings: customerAccessId <- customer.customerAccessId
3. `account_create`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/accounts`, scopes account:write, idempotency required, receipt yes
   - Body: currency, owner, role
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: owner.id <- customer.customerId
4. `sandbox_account_fund`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/sandbox/account-funding`, scopes transfer:write, idempotency required, receipt yes
   - Body: amount, currency, destinationAccountId
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: destinationAccountId <- holder_account.accountId
5. `wallet_create`
   - Actor: product
   - Action: `wallet.create`
   - Route: `POST /v1/wallets`, scopes wallet:write, idempotency required, receipt yes
   - Body: currency, holderAccountId, limitAmount, productId
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: holderAccountId <- holder_account.accountId
6. `wallet_activate`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/wallets/{walletId}/activate`, scopes wallet:write, idempotency required, receipt yes
   - Body: none
   - Path: walletId
   - Query: none
   - Expect: none
   - Bindings: walletId <- wallet.walletId
7. `wallet_topup`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/wallets/{walletId}/topup`, scopes transfer:write, wallet:write, idempotency required, receipt yes
   - Body: amount
   - Path: walletId
   - Query: none
   - Expect: none
   - Bindings: walletId <- wallet.walletId
8. `wallet_withdraw`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/wallets/{walletId}/withdraw`, scopes transfer:write, wallet:write, idempotency required, receipt yes
   - Body: amount
   - Path: walletId
   - Query: none
   - Expect: none
   - Bindings: walletId <- wallet.walletId
9. `wallet_close`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/wallets/{walletId}/close`, scopes wallet:write, idempotency required, receipt yes
   - Body: none
   - Path: walletId
   - Query: none
   - Expect: none
   - Bindings: walletId <- wallet.walletId

### Refund a wallet spend

- Journey id: `refund_wallet_spend`
- Steps: 11

1. `sandbox_customer_onboard`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/sandbox/customer-onboarding`, scopes customer:write, idempotency required, receipt yes
   - Body: displayName, productId
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: none
2. `sandbox_customer_access_activate`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/sandbox/customer-access/{customerAccessId}/activate`, scopes customer:write, idempotency required, receipt yes
   - Body: none
   - Path: customerAccessId
   - Query: none
   - Expect: none
   - Bindings: customerAccessId <- customer.customerAccessId
3. `account_create`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/accounts`, scopes account:write, idempotency required, receipt yes
   - Body: currency, owner, role
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: owner.id <- customer.customerId
4. `account_create`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/accounts`, scopes account:write, idempotency required, receipt yes
   - Body: currency, owner, role
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: owner.id <- customer.customerId
5. `sandbox_account_fund`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/sandbox/account-funding`, scopes transfer:write, idempotency required, receipt yes
   - Body: amount, currency, destinationAccountId
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: destinationAccountId <- holder_account.accountId
6. `wallet_create`
   - Actor: product
   - Action: `wallet.create`
   - Route: `POST /v1/wallets`, scopes wallet:write, idempotency required, receipt yes
   - Body: currency, holderAccountId, limitAmount, productId
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: holderAccountId <- holder_account.accountId
7. `wallet_activate`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/wallets/{walletId}/activate`, scopes wallet:write, idempotency required, receipt yes
   - Body: none
   - Path: walletId
   - Query: none
   - Expect: none
   - Bindings: walletId <- wallet.walletId
8. `wallet_topup`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/wallets/{walletId}/topup`, scopes transfer:write, wallet:write, idempotency required, receipt yes
   - Body: amount
   - Path: walletId
   - Query: none
   - Expect: none
   - Bindings: walletId <- wallet.walletId
9. `wallet_spend_create`
   - Actor: product
   - Action: `wallet_spend.create`
   - Route: `POST /v1/wallet-spends`, scopes wallet_spend:write, idempotency required, receipt yes
   - Body: amount, beneficiaryAccountId, productId, walletId
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: beneficiaryAccountId <- beneficiary_account.accountId, walletId <- wallet.walletId
10. `wallet_spend_post`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/wallet-spends/{walletSpendId}/post`, scopes transfer:write, wallet_spend:write, idempotency required, receipt yes
   - Body: none
   - Path: walletSpendId
   - Query: none
   - Expect: none
   - Bindings: walletSpendId <- spend.walletSpendId
11. `wallet_spend_refund`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/wallet-spends/{walletSpendId}/refund`, scopes transfer:write, wallet_spend:write, idempotency required, receipt yes
   - Body: none
   - Path: walletSpendId
   - Query: none
   - Expect: none
   - Bindings: walletSpendId <- spend.walletSpendId

### Disband an unfilled circle

- Journey id: `disband_unfilled_circle`
- Steps: 2

1. `savings_circle_create`
   - Actor: product
   - Action: `savings_circle.create`
   - Route: `POST /v1/savings-circles`, scopes savings_circle:write, idempotency required, receipt yes
   - Body: contributionAmount, currency, memberCount, memo, productId, startAt
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: none
2. `savings_circle_disband`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/savings-circles/{savingsCircleId}/disband`, scopes savings_circle:write, idempotency required, receipt yes
   - Body: none
   - Path: savingsCircleId
   - Query: none
   - Expect: none
   - Bindings: savingsCircleId <- circle.savingsCircleId

### Withdraw an unstarted membership

- Journey id: `membership_withdrawn`
- Steps: 7

1. `sandbox_customer_onboard`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/sandbox/customer-onboarding`, scopes customer:write, idempotency required, receipt yes
   - Body: displayName, productId
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: none
2. `sandbox_customer_access_activate`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/sandbox/customer-access/{customerAccessId}/activate`, scopes customer:write, idempotency required, receipt yes
   - Body: none
   - Path: customerAccessId
   - Query: none
   - Expect: none
   - Bindings: customerAccessId <- member_customer.customerAccessId
3. `account_create`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/accounts`, scopes account:write, idempotency required, receipt yes
   - Body: currency, owner, role
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: owner.id <- member_customer.customerId
4. `savings_circle_create`
   - Actor: product
   - Action: `savings_circle.create`
   - Route: `POST /v1/savings-circles`, scopes savings_circle:write, idempotency required, receipt yes
   - Body: contributionAmount, currency, memberCount, memo, productId, startAt
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: none
5. `circle_membership_create`
   - Actor: product
   - Action: `circle_membership.create`
   - Route: `POST /v1/circle-memberships`, scopes circle_membership:write, idempotency required, receipt yes
   - Body: joinedAt, memberAccountId, payoutAmount, position, productId, receiveAt, savingsCircleId
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: memberAccountId <- member.accountId, savingsCircleId <- circle.savingsCircleId
6. `savings_circle_disband`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/savings-circles/{savingsCircleId}/disband`, scopes savings_circle:write, idempotency required, receipt yes
   - Body: none
   - Path: savingsCircleId
   - Query: none
   - Expect: none
   - Bindings: savingsCircleId <- circle.savingsCircleId
7. `sandbox_platform_fire`
   - Actor: platform
   - Sandbox trigger: The platform fires `circle_membership.withdraw` in normal lifecycle processing; sandbox fires it now.
   - Action: platform lifecycle trigger
   - Route: `POST /v1/sandbox/platform/fire`, scopes no scopes required, idempotency required, receipt yes
   - Body: input, operation
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: input.circleMembershipId <- membership.circleMembershipId

### Run a rotation

- Journey id: `circles_rotation_cycle`
- Steps: 24

1. `savings_circle_create`
   - Actor: product
   - Action: `savings_circle.create`
   - Route: `POST /v1/savings-circles`, scopes savings_circle:write, idempotency required, receipt yes
   - Body: contributionAmount, currency, memberCount, memo, productId, startAt
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: none
2. `sandbox_customer_onboard`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/sandbox/customer-onboarding`, scopes customer:write, idempotency required, receipt yes
   - Body: displayName, productId
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: none
3. `sandbox_customer_access_activate`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/sandbox/customer-access/{customerAccessId}/activate`, scopes customer:write, idempotency required, receipt yes
   - Body: none
   - Path: customerAccessId
   - Query: none
   - Expect: none
   - Bindings: customerAccessId <- first_member.customerAccessId
4. `account_create`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/accounts`, scopes account:write, idempotency required, receipt yes
   - Body: currency, owner, role
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: owner.id <- first_member.customerId
5. `sandbox_account_fund`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/sandbox/account-funding`, scopes transfer:write, idempotency required, receipt yes
   - Body: amount, currency, destinationAccountId
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: destinationAccountId <- first_account.accountId
6. `sandbox_customer_onboard`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/sandbox/customer-onboarding`, scopes customer:write, idempotency required, receipt yes
   - Body: displayName, productId
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: none
7. `sandbox_customer_access_activate`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/sandbox/customer-access/{customerAccessId}/activate`, scopes customer:write, idempotency required, receipt yes
   - Body: none
   - Path: customerAccessId
   - Query: none
   - Expect: none
   - Bindings: customerAccessId <- second_member.customerAccessId
8. `account_create`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/accounts`, scopes account:write, idempotency required, receipt yes
   - Body: currency, owner, role
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: owner.id <- second_member.customerId
9. `sandbox_account_fund`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/sandbox/account-funding`, scopes transfer:write, idempotency required, receipt yes
   - Body: amount, currency, destinationAccountId
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: destinationAccountId <- second_account.accountId
10. `sandbox_customer_onboard`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/sandbox/customer-onboarding`, scopes customer:write, idempotency required, receipt yes
   - Body: displayName, productId
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: none
11. `sandbox_customer_access_activate`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/sandbox/customer-access/{customerAccessId}/activate`, scopes customer:write, idempotency required, receipt yes
   - Body: none
   - Path: customerAccessId
   - Query: none
   - Expect: none
   - Bindings: customerAccessId <- third_member.customerAccessId
12. `account_create`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/accounts`, scopes account:write, idempotency required, receipt yes
   - Body: currency, owner, role
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: owner.id <- third_member.customerId
13. `sandbox_account_fund`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/sandbox/account-funding`, scopes transfer:write, idempotency required, receipt yes
   - Body: amount, currency, destinationAccountId
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: destinationAccountId <- third_account.accountId
14. `circle_membership_create`
   - Actor: product
   - Action: `circle_membership.create`
   - Route: `POST /v1/circle-memberships`, scopes circle_membership:write, idempotency required, receipt yes
   - Body: joinedAt, memberAccountId, payoutAmount, position, productId, receiveAt, savingsCircleId
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: savingsCircleId <- circle.savingsCircleId, memberAccountId <- first_account.accountId
15. `circle_membership_create`
   - Actor: product
   - Action: `circle_membership.create`
   - Route: `POST /v1/circle-memberships`, scopes circle_membership:write, idempotency required, receipt yes
   - Body: joinedAt, memberAccountId, payoutAmount, position, productId, receiveAt, savingsCircleId
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: savingsCircleId <- circle.savingsCircleId, memberAccountId <- second_account.accountId
16. `circle_membership_create`
   - Actor: product
   - Action: `circle_membership.create`
   - Route: `POST /v1/circle-memberships`, scopes circle_membership:write, idempotency required, receipt yes
   - Body: joinedAt, memberAccountId, payoutAmount, position, productId, receiveAt, savingsCircleId
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: savingsCircleId <- circle.savingsCircleId, memberAccountId <- third_account.accountId
17. `sandbox_platform_fire`
   - Actor: platform
   - Sandbox trigger: The platform fires `savings_circle.activate` in normal lifecycle processing; sandbox fires it now.
   - Action: platform lifecycle trigger
   - Route: `POST /v1/sandbox/platform/fire`, scopes no scopes required, idempotency required, receipt yes
   - Body: input, operation
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: input.savingsCircleId <- circle.savingsCircleId
18. `sandbox_platform_fire`
   - Actor: platform
   - Sandbox trigger: The platform fires `circle_membership.activate` in normal lifecycle processing; sandbox fires it now.
   - Action: platform lifecycle trigger
   - Route: `POST /v1/sandbox/platform/fire`, scopes no scopes required, idempotency required, receipt yes
   - Body: input, operation
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: input.circleMembershipId <- first_seat.circleMembershipId
19. `sandbox_platform_fire`
   - Actor: platform
   - Sandbox trigger: The platform fires `circle_membership.activate` in normal lifecycle processing; sandbox fires it now.
   - Action: platform lifecycle trigger
   - Route: `POST /v1/sandbox/platform/fire`, scopes no scopes required, idempotency required, receipt yes
   - Body: input, operation
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: input.circleMembershipId <- second_seat.circleMembershipId
20. `sandbox_platform_fire`
   - Actor: platform
   - Sandbox trigger: The platform fires `circle_membership.activate` in normal lifecycle processing; sandbox fires it now.
   - Action: platform lifecycle trigger
   - Route: `POST /v1/sandbox/platform/fire`, scopes no scopes required, idempotency required, receipt yes
   - Body: input, operation
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: input.circleMembershipId <- third_seat.circleMembershipId
21. `sandbox_platform_fire`
   - Actor: platform
   - Sandbox trigger: The platform fires `circle_membership.contribute` in normal lifecycle processing; sandbox fires it now.
   - Action: platform lifecycle trigger
   - Route: `POST /v1/sandbox/platform/fire`, scopes no scopes required, idempotency required, receipt yes
   - Body: input, operation
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: input.circleMembershipId <- first_seat.circleMembershipId
22. `sandbox_platform_fire`
   - Actor: platform
   - Sandbox trigger: The platform fires `circle_membership.contribute` in normal lifecycle processing; sandbox fires it now.
   - Action: platform lifecycle trigger
   - Route: `POST /v1/sandbox/platform/fire`, scopes no scopes required, idempotency required, receipt yes
   - Body: input, operation
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: input.circleMembershipId <- second_seat.circleMembershipId
23. `sandbox_platform_fire`
   - Actor: platform
   - Sandbox trigger: The platform fires `circle_membership.contribute` in normal lifecycle processing; sandbox fires it now.
   - Action: platform lifecycle trigger
   - Route: `POST /v1/sandbox/platform/fire`, scopes no scopes required, idempotency required, receipt yes
   - Body: input, operation
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: input.circleMembershipId <- third_seat.circleMembershipId
24. `sandbox_platform_fire`
   - Actor: platform
   - Sandbox trigger: The platform fires `circle_membership.receive_pot` in normal lifecycle processing; sandbox fires it now.
   - Action: platform lifecycle trigger
   - Route: `POST /v1/sandbox/platform/fire`, scopes no scopes required, idempotency required, receipt yes
   - Body: input, operation
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: input.circleMembershipId <- first_seat.circleMembershipId

### Run a member balance

- Journey id: `circles_balance_cycle`
- Steps: 11

1. `sandbox_customer_onboard`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/sandbox/customer-onboarding`, scopes customer:write, idempotency required, receipt yes
   - Body: displayName, productId
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: none
2. `sandbox_customer_access_activate`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/sandbox/customer-access/{customerAccessId}/activate`, scopes customer:write, idempotency required, receipt yes
   - Body: none
   - Path: customerAccessId
   - Query: none
   - Expect: none
   - Bindings: customerAccessId <- member.customerAccessId
3. `account_create`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/accounts`, scopes account:write, idempotency required, receipt yes
   - Body: currency, owner, role
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: owner.id <- member.customerId
4. `sandbox_account_fund`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/sandbox/account-funding`, scopes transfer:write, idempotency required, receipt yes
   - Body: amount, currency, destinationAccountId
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: destinationAccountId <- member_account.accountId
5. `account_create`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/accounts`, scopes account:write, idempotency required, receipt yes
   - Body: currency, owner, role
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: owner.id <- member.customerId
6. `wallet_create`
   - Actor: product
   - Action: `wallet.create`
   - Route: `POST /v1/wallets`, scopes wallet:write, idempotency required, receipt yes
   - Body: currency, holderAccountId, limitAmount, productId
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: holderAccountId <- member_account.accountId
7. `wallet_activate`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/wallets/{walletId}/activate`, scopes wallet:write, idempotency required, receipt yes
   - Body: none
   - Path: walletId
   - Query: none
   - Expect: none
   - Bindings: walletId <- wallet.walletId
8. `wallet_topup`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/wallets/{walletId}/topup`, scopes transfer:write, wallet:write, idempotency required, receipt yes
   - Body: amount
   - Path: walletId
   - Query: none
   - Expect: none
   - Bindings: walletId <- wallet.walletId
9. `wallet_spend_create`
   - Actor: product
   - Action: `wallet_spend.create`
   - Route: `POST /v1/wallet-spends`, scopes wallet_spend:write, idempotency required, receipt yes
   - Body: amount, beneficiaryAccountId, productId, walletId
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: walletId <- wallet.walletId, beneficiaryAccountId <- merchant_account.accountId
10. `wallet_spend_post`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/wallet-spends/{walletSpendId}/post`, scopes transfer:write, wallet_spend:write, idempotency required, receipt yes
   - Body: none
   - Path: walletSpendId
   - Query: none
   - Expect: none
   - Bindings: walletSpendId <- spend.walletSpendId
11. `wallet_withdraw`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/wallets/{walletId}/withdraw`, scopes transfer:write, wallet:write, idempotency required, receipt yes
   - Body: amount
   - Path: walletId
   - Query: none
   - Expect: none
   - Bindings: walletId <- wallet.walletId

### Onboard a member

- Journey id: `circles_member_onboarding`
- Steps: 2

1. `sandbox_customer_onboard`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/sandbox/customer-onboarding`, scopes customer:write, idempotency required, receipt yes
   - Body: displayName, productId
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: none
2. `sandbox_customer_access_activate`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/sandbox/customer-access/{customerAccessId}/activate`, scopes customer:write, idempotency required, receipt yes
   - Body: none
   - Path: customerAccessId
   - Query: none
   - Expect: none
   - Bindings: customerAccessId <- member.customerAccessId

### Move pot funds

- Journey id: `circles_pot_movement`
- Steps: 7

1. `sandbox_customer_onboard`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/sandbox/customer-onboarding`, scopes customer:write, idempotency required, receipt yes
   - Body: displayName, productId
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: none
2. `sandbox_customer_access_activate`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/sandbox/customer-access/{customerAccessId}/activate`, scopes customer:write, idempotency required, receipt yes
   - Body: none
   - Path: customerAccessId
   - Query: none
   - Expect: none
   - Bindings: customerAccessId <- source.customerAccessId
3. `account_create`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/accounts`, scopes account:write, idempotency required, receipt yes
   - Body: currency, owner, role
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: owner.id <- source.customerId
4. `sandbox_account_fund`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/sandbox/account-funding`, scopes transfer:write, idempotency required, receipt yes
   - Body: amount, currency, destinationAccountId
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: destinationAccountId <- source_account.accountId
5. `account_create`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/accounts`, scopes account:write, idempotency required, receipt yes
   - Body: currency, owner, role
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: owner.id <- source.customerId
6. `internal_transfer_reserve`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/internal-transfers/reserve`, scopes transfer:write, idempotency required, receipt yes
   - Body: amount, currency, destinationAccountId, memo, sourceAccountId
   - Path: none
   - Query: none
   - Expect: none
   - Bindings: sourceAccountId <- source_account.accountId, destinationAccountId <- pot_account.accountId
7. `internal_transfer_post`
   - Actor: product
   - Action: platform write
   - Route: `POST /v1/internal-transfers/{transferId}/post`, scopes transfer:write, idempotency required, receipt yes
   - Body: none
   - Path: transferId
   - Query: none
   - Expect: none
   - Bindings: transferId <- pot.transferId

## Cost

Cost table version 2026-09-02.1. Flat amounts are multiplied by the action count; basis points price the meter's moved amount, which an action count does not determine.

| Instrument | Action | Effect | Meter | Flat per action | Rate on meter | 1,000 per month | 100,000 per month | 10,000,000 per month |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| `circle_membership` | `activate` | `schedules.due` | `instrument.event.count` | 0.00 SAR | 0 bps | 0.00 SAR | 0.00 SAR | 0.00 SAR |
| `circle_membership` | `contribute` | `moves.transfer.internal` | `transfer.internal.volume_sar` | 0.75 SAR | 11 bps | 750.00 SAR | 75,000.00 SAR | 7,500,000.00 SAR |
| `circle_membership` | `contribute` | `schedules.due` | `instrument.event.count` | 0.00 SAR | 0 bps | 0.00 SAR | 0.00 SAR | 0.00 SAR |
| `circle_membership` | `create` | `reads.requires_refs` | `instrument.event.count` | 0.00 SAR | 0 bps | 0.00 SAR | 0.00 SAR | 0.00 SAR |
| `circle_membership` | `receive_pot` | `moves.transfer.internal` | `transfer.internal.volume_sar` | 0.75 SAR | 11 bps | 750.00 SAR | 75,000.00 SAR | 7,500,000.00 SAR |
| `circle_membership` | `receive_pot` | `reads.requires_aggregate` | `instrument.event.count` | 0.00 SAR | 0 bps | 0.00 SAR | 0.00 SAR | 0.00 SAR |
| `circle_membership` | `receive_pot` | `schedules.due` | `instrument.event.count` | 0.00 SAR | 0 bps | 0.00 SAR | 0.00 SAR | 0.00 SAR |
| `circle_membership` | `withdraw` | `schedules.due` | `instrument.event.count` | 0.00 SAR | 0 bps | 0.00 SAR | 0.00 SAR | 0.00 SAR |
| `savings_circle` | `activate` | `reads.requires_aggregate` | `instrument.event.count` | 0.00 SAR | 0 bps | 0.00 SAR | 0.00 SAR | 0.00 SAR |
| `savings_circle` | `activate` | `schedules.due` | `instrument.event.count` | 0.00 SAR | 0 bps | 0.00 SAR | 0.00 SAR | 0.00 SAR |
| `savings_circle` | `close` | `reads.requires_aggregate` | `instrument.event.count` | 0.00 SAR | 0 bps | 0.00 SAR | 0.00 SAR | 0.00 SAR |
| `wallet` | `topup` | `moves.transfer.internal` | `transfer.internal.volume_sar` | 0.75 SAR | 11 bps | 750.00 SAR | 75,000.00 SAR | 7,500,000.00 SAR |
| `wallet` | `withdraw` | `moves.transfer.internal` | `transfer.internal.volume_sar` | 0.75 SAR | 11 bps | 750.00 SAR | 75,000.00 SAR | 7,500,000.00 SAR |
| `wallet_spend` | `create` | `reads.requires_refs` | `instrument.event.count` | 0.00 SAR | 0 bps | 0.00 SAR | 0.00 SAR | 0.00 SAR |
| `wallet_spend` | `post` | `moves.transfer.internal` | `transfer.internal.volume_sar` | 0.75 SAR | 11 bps | 750.00 SAR | 75,000.00 SAR | 7,500,000.00 SAR |
| `wallet_spend` | `post` | `reads.requires_refs` | `instrument.event.count` | 0.00 SAR | 0 bps | 0.00 SAR | 0.00 SAR | 0.00 SAR |
| `wallet_spend` | `refund` | `moves.transfer.internal` | `transfer.internal.volume_sar` | 0.75 SAR | 11 bps | 750.00 SAR | 75,000.00 SAR | 7,500,000.00 SAR |
| **Total flat** | | | | | | **4,500.00 SAR** | **450,000.00 SAR** | **45,000,000.00 SAR** |
