Proposal: Supporting Auth/Capture Payments with Claimable Balances

89 views
Skip to first unread message

Leigh McCulloch

unread,
Feb 17, 2021, 5:32:02 PM2/17/21
to Stellar Developers
Proposal:

We define an indicator that merchants can use to signal to wallets that payment should be made via a claimable balance rather than as a direct payment to the account.

1. Buyer chooses to buy item or goes to checkout page.
2. Merchant specifies a muxed account for the destination of payment.
3. Merchant monitors for a claimable balance with a claimant of the muxed account.
4. Buyer sends payment via a claimable balance to the muxed account, adding themselves as a claimant as well.
5. Merchant finds claimable balance and verifies it is an exact payment.
6. Merchant claims claimable balance, updates internal records of payment, and makes the digital item available for download.
7. If there is anything wrong with the claimable balance, or communication with the merchant breaks down, the merchant can ask them to try again, or the buyer can claim back the claimable balance and send a new one.

Note: Replace muxed accounts with memos in a world that muxed accounts have not been implemented in SDKs yet, like where we are today.

Why:

To simplify Stellar integrations for merchants who already accept card payments.

Merchants who accept card payments typically integrate with payment gateways using a two-step model: authorization and capture.

Authorization locks up the amount on the account for a predefined number of days or until the authorization is voided, whichever occurs first. Authorizations typically display as pending transactions to consumers on their digital bank statements.

Capture moves an authorization into clearing to start the process of moving funds from the card issuing bank to the acquiring bank of the merchant. Merchants typically capture an authorization when delivery is being made, such as shipping a product or making it available for download. Separating capture into a second step allows merchants to run additional checks on the buyers method of payment, display a confirmation screen before finalizing payment, and binding operations on the backend that are easier if done together.

This two-step model simplifies payment flows because merchants do not need to monitor payments to accounts, verify amounts, and deal with refunds or reversals for overpayment, underpayment, etc.

Payments on Stellar are push payments. The wallet pushes money to an account and the merchant must identify it, verify if it is an exact payment, underpayment, overpayment, and issue refunds, etc. This complicates integrations for merchants who only do auth/capture payments. But claimable balances provide us with a mechanism for supporting auth/capture style payments natively and simplifying their integrations.

Possible approaches:

This proposal should become a CAP and a SEP:

CAP: An account flag indicating that it cannot receive payments directly.
SEP: Define how wallets identify claimable balances should be sent, and recommended claimants to ensure a wallet can claim back a payment.

Alternatively the CAP could be a SEP if the indicator was implemented as:

1. Data entry on the account indicating that payment should be via a claimable balance. SDKs could fail payments to these accounts in the same way they fail payments to accounts requiring memos when no memo is included.

2. Accounts could keep their trustlines disabled, add a trustline temporarily when claiming the balance, send the balance to another account, then remove the trustline in the same transactions. Wallets could default to sending claimable balances to accounts without a trustline.

Both SEP-only approaches have limitations and problems.

Alternatives with what we have today:

Merchants can already display SEP-7 URLs or QR Codes to wallets that craft the request to be a claimable balance, however it is more common to use simple QR Codes that contain only the destination account, and not all wallets use SEP-7.

Next steps:

I'd like to explore a CAP proposal that prevents payments from being sent to accounts that have incoming payments disabled. I think this change would be rather simple, and would be useful in cases beyond this such as smart contracts which need the balance of an account to be predictable.

Does anyone have thoughts about this? Would anyone be opposed to a CAP that makes this proposal and a corresponding SEP that defines how wallets should interact with it?

Jonathan Jove

unread,
Feb 17, 2021, 6:06:25 PM2/17/21
to Leigh McCulloch, Stellar Developers
Hi Leigh,

Interesting proposal. There actually is a draft CAP that is an even more aggressive version of what is proposed here (albeit with a relatively opaque name): https://github.com/stellar/stellar-protocol/blob/master/core/cap-0009.md. I have mixed feelings about some aspects of that CAP, but it might be a starting point for discussion.

Thanks,
Jon

--
You received this message because you are subscribed to the Google Groups "Stellar Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to stellar-dev...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/stellar-dev/643cddc9-5a40-4496-8f16-36417b67aa83n%40googlegroups.com.

Leigh McCulloch

unread,
Feb 17, 2021, 6:55:25 PM2/17/21
to Jonathan Jove, Stellar Developers
Hi Jon,

Thanks, I've reviewed SEP-9 and I think that goes well beyond what is needed for this use case. What would be needed for this use case is the inability for another account to increase a trustlines balance (unless interacting through an offer on the account).

SEP-9 proposes configurability on whether the transaction should temporarily fail or permanently fail. I don't think I understand the intended behavior and use case, but I'd prefer it if when the flag is set, payments cannot be accepted, and when it is not set, payments can be accepted, and if AUTH_IMMUTABLE is set that is the feature that controls if the flag can be changed or not.

SEP-9 also proposes a partially locked state where a new signature type will allow for operations to be performed. I think this use case could be addressed with the cooperation of the receiving account to sign sandwich-like operations that disable the flag and re-enable it after the operation.

SEP-9 also broadly proposes that no change to an account should be possible, but I think we could constrain a new proposal to say that the trustline balance cannot be increased without participation of the account through claiming a claimable balance, or the processing of an offer.

What do you think?

Jonathan Jove

unread,
Feb 18, 2021, 10:33:40 AM2/18/21
to Leigh McCulloch, Stellar Developers
Before we discuss a CAP approach any further, I want to make sure I understand the challenges with the SEP approach(es). Specifically, let's discuss the "trustlines disabled" approach because it is quite close to what could be achieved by changing the protocol in the sense that even applications that are unaware will not be able to violate the invariant.

One challenge with your approach of adding/removing the trustline in a sandwich is that it will destroy the flags on the trustline such as AUTHORIZED_FLAG. Are there other challenges that appear? I have explored a similar concept in the past for other reasons, and I have a slightly different proposal about how this could be implemented. Rather than actually adding/removing the trustline, the account could bump the limit by the exact amount required in the same transaction as claiming the balance. This preserves flags, permits offers, and will have a marginally lower fee cost.

This, however, doesn't work directly for the native asset because they don't have a limit. First, it's not totally clear to me that people would actually need this functionality for the native asset (do they?). But assuming they do, it is possible to achieve because liabilities provide a way to imitate limits for the native asset. This can be done by creating an offer that sells an asset that no one can hold (achievable by just creating an authorization required asset) and buys the native asset at a 1:1 price with amount equal to INT64_MAX - accountBalance. I acknowledge that this is functional but not appealing for the native asset, but perhaps it could be wrapped behind a nice SDK interface.

My main question is: does this approach have any obvious downsides relative to a protocol-level implementation? If so, let's analyze them to understand where we can make improvements.

Leigh McCulloch

unread,
Feb 18, 2021, 10:56:57 AM2/18/21
to Stellar Developers
Another challenge with the sandwich add/remove trustlines approach is that some wallets use a missing trustline at the destination as a trigger for offering path payments to the user. There would be no way for the wallet to know if it should offer path payments to XLM, or send a claimable balance.

I think this should work the same way for all asset types. The approach you describe is extremely complicated for an account holder or developer to understand. While an SDK might be able to abstract the interactions to set it up, it won't abstract the account state which will be visible to on explorers and likely to raise questions and create confusion. The process of temporarily removing the lock to perform some sort of administrative options is also odd and difficult to explain. It would also be difficult to claim XLM claimable balances because the account holder would have to adjust the offer to allow for the claimable balance's amount to be held alongside the offer, and it would be a very odd SDK API to support that.

Nicolas Barry

unread,
Feb 22, 2021, 9:38:50 PM2/22/21
to Leigh McCulloch, Stellar Developers
Yeah having this apply to the native balance is problematic when trying to "salvage" an account in various situations.

For example, if an account uses all their available balance (and can't pay for fees) or if the base reserve ever increases: the recovery involves performing a multi-sig transaction with (likely) an exchange, whereas today you can unstick an account by withdrawing from an exchange which is simple/intuitive for people.

nicolas


On Thu, Feb 18, 2021 at 7:56 AM 'Leigh McCulloch' via Stellar Developers <stell...@googlegroups.com> wrote:
Another challenge with the sandwich add/remove trustlines approach is that some wallets use a missing trustline at the destination as a trigger for offering path payments to the user. There would be no way for the wallet to know if it should offer path payments to XLM, or send a claimable balance.

I think this should work the same way for all asset types. The approach you describe is extremely complicated for an account holder or developer to understand. While an SDK might be able to abstract the interactions to set it up, it won't abstract the account state which will be visible to on explorers and likely to raise questions and create confusion. The process of temporarily removing the lock to perform some sort of administrative options is also odd and difficult to explain. It would also be difficult to claim XLM claimable balances because the account holder would have to adjust the offer to allow for the claimable balance's amount to be held alongside the offer, and it would be a very odd SDK API to support that.

--
You received this message because you are subscribed to the Google Groups "Stellar Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to stellar-dev...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages