mpp pay always fails against mppx >= 0.15 servers: "MPP challenge changed after approval" (per-challenge nonce in opaque is not excluded from the comparison)
Maintainer thường phản hồi trong vòng 1 ngày
Đánh giá
- Độ khó
- 3/5
- Thời gian dự kiến
- 1-2 ngày
- Mức phù hợp với người mới
- 72/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- node.js, typescript
Hướng nghiên cứu
Start in comparableChallenge in link-cli, which the issue identifies as neutralizing id and expires before the approved challenge is compared with a fresh probe. Read the challenge serialization and approval comparison flow, including payPinnedChallengeWithSpt and runMppPayFullFlow. Reproduce with an mppx 0.15 server and verify the same approved payment succeeds when only issuance metadata differs.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Summary
Against a seller using mppx 0.15.0 (Stripe SPT charge), link-cli mpp pay can never complete a payment. After the spend request is approved, link-cli re-probes the endpoint and compares the fresh 402 challenge to the approved one. mppx adds fresh random issuance metadata (_mppx_nonce) to every challenge's opaque field by design, so the comparison always fails:
Error: MPP challenge changed after approval; refusing to use the approved payment credential
The amount, currency, realm, method, intent, request, and description are identical between the two challenges. Only id, expires, and the nonce in opaque differ.
Versions
@stripe/link-cli0.30.0mppx0.15.0 (server:Mppxfrommppx/server/corewithstripe.spt(...)frommppx/stripe/server/spt)- Node.js 20 and 24, Stripe test mode,
--test
Steps to reproduce
- Run an MPP endpoint with mppx 0.15.0 and a Stripe SPT charge, for example
mppx.charge({ amount: '0.75', currency: 'usd', decimals: 2 })(request). link-cli mpp pay <url> --method POST --data '<json>' --test --context "<100+ chars>"- Approve the spend request in Link.
- Run the returned
_next.pay_argv(mpp pay <url> --spend-request-id <id> --approved-challenge '<challenge>' ...). - It fails with the error above. The interactive (TTY) flow fails the same way, because
runMppPayFullFlowalso ends inpayPinnedChallengeWithSpt(probe, spt, approvedChallenge).
Cause
comparableChallenge in link-cli only neutralizes id and expires:
function comparableChallenge(challenge) {
return Challenge2.serialize({ ...challenge, id: "approval-comparison", expires: void 0 });
}
mppx adds a fresh nonce to every issued challenge (server/internal/challengeMeta.js):
/** Reserved metadata key for HMAC-bound, per-issuance challenge randomness. */
const nonceKey = '_mppx_nonce';
export function withNonce(meta) { return { ...meta, [nonceKey]: Secp256k1.randomPrivateKey() }; }
/** Removes issuance-only metadata when comparing stable route requirements. */
export function routeMeta(meta) { const { [nonceKey]: _, ...rest } = meta ?? {}; ... }
withNonce is applied in server/Mppx.js when challenges are created, so two challenges for the same route are never byte-identical. mppx's own routeMeta() shows the intended comparison: strip _mppx_nonce.
Suggested fix
In comparableChallenge, also drop issuance-only metadata from opaque, specifically the _mppx_nonce key, mirroring mppx's routeMeta(). Alternatively, compare only the fields the shopper actually approved (realm, method, intent, decoded request: amount, currency, network ID, external ID).
Workaround
The approved token itself is valid. Retrieving it with spend-request retrieve <id> --include shared_payment_token and paying a fresh challenge with the mppx client (stripe.charge({ createToken: () => spt })) succeeds. The SPT's own limits (amount, network ID, expiry) still apply.
- Ngôn ngữ chính
- TypeScript
- Star
- 873
- Fork
- 147
- Merge trung bình
- 23 giờ 53 phút
- Pull request đã merge (30 ngày)
- 76
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Không có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của stripe/link-cli
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 74/100
Maintainer thường phản hồi trong vòng 1 ngày
-
`balances list` renders non-USD balances with a `$` symbol and a fixed `/100`Có thể đã có người làm @RaphaelFakhri đã nhận 3 ngày trước. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 25/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 42/100
stripe/link-cli#479 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 1/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 25/100
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của stripe/link-cli
Issue tương tự
-
New icon: `filter-clear`Đang mởcalcite-ui-icons enhancement impact - p3 - not time sensitive needs triage
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 67/100
Esri/calcite-design-system#15467 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
diegosouzapw/OmniRoute#18390 ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
-
Độ khó 1/5 1-3 giờ Mức phù hợp với người mới 86/100
guilhermerodz/input-otp#157 · 1 bình luận ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
davidjerleke/embla-carousel#1414 ·
Maintainer thường phản hồi trong vòng 4 ngày