Repository navigation
feat(skills): rework payments around the placed-cart lock, add Mollie and Two - #26
Merged
Merged
Conversation
… and Two - SKILL.md: the common flow from the crystallize.com docs, why the cart is placed before charging (the two-tab attack), one payment per cart, the webhook skeleton, a read-only return page, shared Shop API helpers (/lock, createOrderOnce, Core customer, recordPayment, updatePayment), paymentStatus set once at creation, and capture/cancel from fulfilment pipeline stages. - Every provider reference re-verified against current provider docs (2026-10-06), with the crystallize.com page content folded in and provider-specific features kept as plain API calls. - New references: Mollie (Payments API) and Two (B2B invoice). - No dependency on the deprecated request-handler library or old boilerplates.
A skill page inlines SKILL.md and its references/*.md into one document, but the relative .md links between those files were rendered as-is, so links like references/plans-and-pricing.md 404ed. Each reference now gets an anchor above its section, and links to a reference, a SKILL.md or another skill's files are rewritten to the page and anchor they ended up on.
createOrderOnce, recordPayment and updatePayment no longer take the Shop API lock, and the Dintero, Qliro and Two pay routes no longer hold it in the shopper's path. A new 'Serialising order writes (optional)' section explains what colliding deliveries can lose without it, what it costs, and when to opt in. The helper intro now says why shop() exists: shopCartApi only reaches /cart.
lib/crystallize-payments.ts drops the hand-rolled shopToken()/shop(): orders go through createShopOrderManager, the 'create the customer if missing' step through createShopCustomerManager (fetch, then upsert only when absent, nulls stripped), and the opt-in lock through createShopLock. One client token covers the cart, order and customer scopes.
- js-api-client: the five new shop*Api callers, the shared Shop API token and its scopes, createShopOrderManager, createShopCustomerManager and createShopLock with their gotchas (meta read back as an object, writes persist after the response, optional fields reject null), Core vs Shop helpers marked in the table, and when to use createOrderManager (Core) vs createShopOrderManager (Shop). - mutation: the JS snippet uses nextPimApi for Core and shows the Shop API callers. - payments: description trimmed under the 1024-character skill limit.
Plopix
added a commit
that referenced
this pull request
Oct 7, 2026
Deploy Docs only starts when a CI push run on main completes. The merge of #26 never got a CI push run (GitHub Webhooks were degraded at the time) and the release commit is pushed with GITHUB_TOKEN, which triggers nothing, so the docs stayed on f8b6405 without the skill-link rewrite. A workflow_dispatch trigger, limited to main, gives a way to deploy anyway.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Reworks the
paymentsskill from the crystallize.com payment-gateway docs, without the deprecated Node request-handler library.SKILL.md
placeprevents it:createFromCartrefuses a cart that isn't placed. It also explains thatplacere-prices the cart, and that writes to a placed cart are silently dropped.createOrderOnce:/lock;createFromCartonce;ordered.placed.paymentStatusis set once, at creation.createSignatureVerifier, calls the provider, thensetPaymentsupdates the record.References
tsc --strictagainst@crystallize/js-api-client7.4 and the providers' SDKs. Nothing was run end-to-end against a provider.How it was tested
Following the writing-skills process, each scenario was run without the skill first, then with it, and the written answers were compared. Nothing was executed.
updateOrder.Needs a decision on the platform side
/ordercan't changepaymentStatusafter creation.addPaymentsandsetPaymentstake onlyidandpayments. Patching it through CoreupdateOrderpushes Core's whole order back to the Shop store, which can overwrite the payments just set. So the skill leavespaymentStatusas created, and the payment record'smeta.statetracks capture and refund. AsetPaymentStatusmutation on Shop/orderwould fix this.paymentStatusalongside your payment updates". The API doesn't support that.Not done
bun run bin/eval-reference-selection.ts) failed with a Workers AI authentication error. Wrangler is logged in to a different Cloudflare account than the one pinned inwrangler.jsonc. The Mollie and Two cases are added and ready to run.Requires
@crystallize/js-api-client7.5.0 (published)The shared helper uses
createShopOrderManager,createShopCustomerManagerandcreateShopLockfrom@crystallize/js-api-client7.5.0, which builds on@crystallize/schema6.15.0. Both are now on npm. Every code block inpayments(SKILL.md and the 11 references) and injs-api-clientwas re-checked withtsc --strictagainst the published packages.The Shop API
/lockis opt-in, under "Serialising order writes (optional)". It is never used by default or in the Pay route.js-api-client and mutation skills (consequences of 7.5)
js-api-client:shop*Apicallers.scopes.createShopOrderManager,createShopCustomerManagerandcreateShopLock, with their gotchas:metais read back as an object, writes persist just after the response, and optional fields rejectnull.createOrderManager(Core) vscreateShopOrderManager(Shop).createOrderManagerfor a cart-based order. With it, the agent answered all five Shop API questions correctly.mutation: the JS snippet now usesnextPimApifor Core instead of the legacypimApi, and shows the Shop API callers.payments: the description is trimmed under the 1024-character skill limit.