The weekend package checkout is the flagship Blue example. It models a real two-stage checkout: customer payment is secured first, the reseller attaches or creates the hotel and restaurant orders, the PayNote requests completion only after both merchant confirmations arrive, and the parent package order becomes ready_to_use only after payment completion.
The source example is reseller-weekend-package-offer-contract-bex-authoring.yaml. The full document is embedded near the end of this page, after the guided explanation, with the first section visible and the rest hidden behind a read-more disclosure.
Most workflow examples are too small. They change a status and call it a day. Real business flows are harder:
The weekend package example has all of that without becoming abstract. It has a recognizable product: a romantic weekend with a hotel stay and restaurant dinner. It has concrete roles: customer, reseller, hotel, restaurant, and payment guarantor. It has obvious business safety rules. It has enough BEX to show real guards and state transitions.
It is perfect because it is the same model as Counter, scaled to a flow people actually care about.
The offer is sold by ITC / mega-pakiety.pl. The customer buys a package that includes:
49900 minor units.The package order starts in a cautious state. It is not ready for checkout until the provider confirms and attaches a checkout payload. The customer payment is represented by a PayNote. The PayNote secures funds first and requests completion only after both included merchant orders confirm.
At the end, the package order should say:
1status: ready_to_use2payment:3 state: completed
That final state is not a hand-written status update. It is the result of processing events across the package order, embedded PayNote, and embedded merchant orders.
The source document has this shape:
1Package Offer2├─ product-facing fields3│ ├─ seller4│ ├─ price5│ └─ customerSummary6├─ orderTemplate7│ └─ document: Package Order8│ ├─ status9│ ├─ payment10│ ├─ components11│ ├─ embeddedDocs12│ │ ├─ packagePayNote13│ │ └─ orders14│ │ ├─ hotelOrder15│ │ └─ restaurantOrder16│ └─ contracts17│ ├─ customer/investor channels18│ ├─ embedded PayNote event channel19│ ├─ process embedded docs20│ ├─ package operations21│ └─ BEX Compute workflows22└─ offer-level contracts23 ├─ anchors24 ├─ investor channel25 └─ lifecycle initialization
This structure is important. The offer is not the live order. The offer contains an order template. A live customer order can be created from that template and then processed through its own timeline entries.
That is a practical pattern for commerce documents. Product content and process template live together, but each customer order becomes its own processable document.
Before reading any BEX, read the package order state:
1orderTemplate:2 document:3 name: Romantic Weekend with a Premium Dinner for Two Order4 kind: Package Order5 status: awaiting_provider_confirmation6 price:7 amountMinor: 499008 currency: PLN9 payment:10 tokenAttached: false11 payNoteAttached: false12 state: not_started13 paymentToken: ''14 expectedPayNoteDescriptor: {}15 checkoutMetadata: {}16 components:17 hotel:18 status: not_started19 orderAttached: false20 restaurant:21 status: not_started22 orderAttached: false23 embeddedDocs:24 orders: {}
This is the business surface. Even without reading contracts, you can see the initial assumptions:
The contracts explain how those fields are allowed to change.
The source document uses several channels:
1customerChannel:2 type: MyOS/MyOS Timeline Channel3investorChannel:4 type: MyOS/MyOS Timeline Channel5embeddedPackagePayNoteEvents:6 type: Core/Embedded Node Channel7 childPath: /embeddedDocs/packagePayNote
Inside the PayNote descriptor, there are payer, payee, and guarantor channels:
1payerChannel:2 type: MyOS/MyOS Timeline Channel3payeeChannel:4 type: MyOS/MyOS Timeline Channel5guarantorChannel:6 type: MyOS/MyOS Timeline Channel
Read these as boundaries of authority and evidence. The reseller/provider uses one channel to confirm the package and attach checkout payloads. The PayNote uses participant and guarantor channels for payment lifecycle evidence. Embedded node channels let parent and child documents observe each other's emitted events.
The exact production trust model belongs to the host timeline provider. The document still makes the routing explicit.
The flow can be read as a sequence of state transitions:
| Step | Trigger | Main result |
|---|---|---|
| 1 | Offer exists | kind: Offer, status: active, order template available. |
| 2 | Package order starts | Order begins awaiting_provider_confirmation. |
| 3 | Reseller confirms | Status moves toward checkout preparation. |
| 4 | Reseller attaches checkout payload | Payment token and expected PayNote descriptor are stored; order becomes ready_for_checkout. |
| 5 | PayNote is attached | PayNote snapshot is embedded; payment.payNoteAttached = true. |
| 6 | PayNote secures funds | Parent package marks payment.state = payment_secured. |
| 7 | Hotel order attaches | Hotel order snapshot is embedded; hotel component is marked attached. |
| 8 | Restaurant order attaches | Restaurant order snapshot is embedded; restaurant component is marked attached. |
| 9 | Hotel confirms | Hotel order confirmation status becomes confirmed. |
| 10 | Restaurant confirms | Restaurant order confirmation status becomes confirmed. |
| 11 | PayNote observes both confirmations | PayNote emits PayNote/Complete Payment Requested. |
| 12 | Payment completes | PayNote emits PayNote/Payment Completed. |
| 13 | Parent reacts to PayNote completion | Package status becomes ready_to_use; payment state becomes completed. |
The order is the point. Payment is not completed merely because the customer clicked checkout. It completes after merchant confirmation evidence is present.
The package order has a confirmOrder operation. Its job is to move the order from awaiting provider confirmation into a state where checkout can be prepared.
The workflow checks whether the order is already in a later state. If so, it returns unchanged. Otherwise, it writes a provider-confirmed pending-payment-token state and emits an order-confirmed event.
This is a basic but important guard pattern:
1- $if:2 cond:3 $or:4 - $eq: [ { $document: /status }, provider_confirmed_pending_payment_token ]5 - $eq: [ { $document: /status }, ready_for_checkout ]6 - $eq: [ { $document: /status }, ready_to_use ]7 then:8 - $return:9 changeset:10 $changeset: true11 events:12 $events: true
The exact source uses the ordinary BEX YAML shape rather than the compact inline list style above. The concept is the same: do not repeat a state transition that already happened.
attachPaymentToken stores a one-time checkout token and an expected PayNote descriptor prepared by the reseller.
The operation is guarded in three ways:
The successful branch writes several fields:
1- $appendChange:2 op: replace3 path: /payment/tokenAttached4 val: true5- $appendChange:6 op: replace7 path: /payment/paymentToken8 val:9 $event: /message/request/paymentToken10- $appendChange:11 op: replace12 path: /payment/expectedPayNoteDescriptor13 val:14 $event: /message/request/expectedPayNoteDescriptor15- $appendChange:16 op: replace17 path: /status18 val: ready_for_checkout19- $appendEvent:20 type: Conversation/Event21 kind: Payment Token Attached22 orderKind: package
This is a good Stripe-like moment in the flow: checkout readiness is not a vague boolean. It is the result of a provider-confirmed package order plus a stored payment token plus an expected PayNote descriptor.
The expected PayNote descriptor says what payment document should appear:
1expectedPayNoteDescriptor:2 document:3 name: Customer to ITC / mega-pakiety.pl Package PayNote4 type: PayNote/PayNote5 kind: PayNote6 description: Customer package payment secured before provider orders.7 state:8 type: Text9 currency: PLN10 amount:11 expectedTotal: 4990012 context:13 scenario: reseller-weekend-package14 paymentKind: customer_package_purchase
A PayNote is a document that governs one transaction. It is not the payment rail. It records the participant roles, expected amount, lifecycle state, requests, guarantor responses, and evidence around securing and completing the transaction.
In this example, the PayNote's purpose is specific: secure the customer package payment before provider orders, then complete payment after both merchant orders confirm.
That is exactly the kind of rule that should not be buried in a checkout controller.
attachPayNote embeds the real PayNote snapshot under the package order:
1- $appendChange:2 op: add3 path: /embeddedDocs/packagePayNote4 val:5 $event: /message/request/initialSnapshot6- $appendChange:7 op: replace8 path: /payment/payNoteAttached9 val: true
Before that, the workflow validates that the snapshot looks like the expected package PayNote:
kind: PayNote;context.paymentKind: customer_package_purchase;If validation fails, the workflow emits a PayNote attachment rejection event. That makes invalid evidence visible.
If validation succeeds, the package embeds the PayNote and may move payment state to paynote_attached unless payment is already secured or completed.
The parent package order listens to events from the embedded PayNote:
1embeddedPackagePayNoteEvents:2 type: Core/Embedded Node Channel3 childPath: /embeddedDocs/packagePayNote
When the embedded PayNote emits PayNote/Funds Secured, the parent workflow marks payment secured:
1- $appendChange:2 op: replace3 path: /payment/state4 val: payment_secured
This matters because the package should not start treating downstream merchant orders as safe until the payment is secured. Again, Blue is not moving money. It is recording and reacting to authoritative payment evidence delivered through the PayNote.
The package includes two merchant orders: hotel and restaurant. The same operation shape can attach either one:
1attachComponentOrder:2 type: Coordination/Operation3 description: Attaches an initial snapshot of one included merchant order to this package order.4 channel: investorChannel5 request:6 kind:7 type: Text8 initialSnapshot:9 kind: Order10 orderKind:11 type: Text12 context:13 packageOrderDocumentId:14 type: Text15 orderSessionId:16 type: Text
The BEX checks the requested kind and snapshot shape. A hotel attachment must include a hotel order snapshot. A restaurant attachment must include a restaurant order snapshot.
The key idempotency logic compares existing and incoming identity:
1sameExisting:2 $or:3 - $var: sameExistingByDocumentId4 - $var: sameExistingBySessionId
If an order is already attached and the new snapshot is different, the workflow emits a rejection event:
1- $appendEvent:2 type: Conversation/Event3 kind: Component Order Attachment Rejected4 orderKind: hotel5 reason: component_order_already_attached
If there is no existing order, it adds the snapshot. If the existing order matches, it can replace/update the slot. The patch operation is chosen dynamically:
1op:2 $choose:3 cond:4 $var: hasExisting5 then: replace6 else: add
This is one of the best parts of the example. It shows BEX doing real workflow work: not just arithmetic, but safe document evolution under duplicate and conflicting inputs.
Inside the PayNote, completion should be requested only after both merchant orders confirm. The PayNote observes embedded hotel and restaurant order events through embedded node channels.
The guard checks three things:
confirmed.confirmed.The core shape is:
1- $if:2 cond:3 $or:4 - $ne:5 - $document: /embeddedDocs/orders/hotelOrder/confirmation/status6 - confirmed7 - $ne:8 - $document: /embeddedDocs/orders/restaurantOrder/confirmation/status9 - confirmed10 - $truthy:11 $document: /completionRequested12 then:13 - $return:14 changeset:15 $changeset: true16 events:17 $events: true18- $appendChange:19 op: replace20 path: /completionRequested21 val: true22- $appendEvent:23 type: PayNote/Complete Payment Requested24 amount: 49900
This is the heart of the checkout safety model. A single merchant confirmation is not enough. A duplicate confirmation after completion has already been requested is not enough. Only the first moment when both confirmations are present produces the completion request.
The parent package order becomes ready when the embedded PayNote emits PayNote/Payment Completed.
The parent workflow writes:
1- $appendChange:2 op: replace3 path: /status4 val: ready_to_use5- $appendChange:6 op: replace7 path: /payment/state8 val: completed
It can also emit a package-ready event:
1- $appendEvent:2 type: Conversation/Event3 kind: Package Ready To Use4 orderKind: package
Notice the layering. The PayNote requests completion after both confirmations. The guarantor or payment rail eventually provides completion evidence. The parent package reacts to that evidence. The package does not mark itself ready merely because the PayNote requested completion.
That separation is what makes the flow auditable.
The source document is large, but the core invariants are clear:
| Invariant | Why it matters |
|---|---|
| A payment token cannot be attached before provider confirmation. | Prevents checkout before the seller accepts the package order. |
| A PayNote must match the current package order. | Prevents embedding a payment document for the wrong order. |
| A component order cannot be replaced by a different order after attachment. | Prevents corrupting the package with conflicting merchant snapshots. |
| Payment completion is requested only after both merchant confirmations. | Enforces the two-stage checkout rule. |
| Completion is requested only once. | Prevents duplicate capture/settlement requests. |
The package becomes ready_to_use only after PayNote completion. | Keeps customer readiness tied to payment governance evidence. |
These invariants should become tests.
Build a replay fixture around the full source document embedded below:
attachPaymentToken with a token and expected PayNote descriptor.attachPayNote with a PayNote snapshot bound to this package order.PayNote/Funds Secured event from the embedded PayNote.attachComponentOrder for the hotel order.attachComponentOrder for the restaurant order.PayNote/Complete Payment Requested event.ready_to_use.completed.This replay test should be the integration benchmark for the docs.
The document does not call a card API. It does not call Hotel Badura's booking system. It does not call Restaurant Cud Malina's reservation system. It does not decide by itself that a payment rail action has succeeded.
Those actions belong to host systems. Blue represents the process state and deterministic rules around the evidence those systems deliver.
For example, PayNote/Complete Payment Requested is a document event. A payment adapter may listen for it and attempt capture or settlement. The authoritative result comes back as a guarantor/payment event, such as payment completed, failed, declined, reversed, or cancelled depending on the PayNote profile.
That boundary is exactly why the example is good. It does not pretend document logic replaces external systems. It shows how document logic can make external-system coordination inspectable.
Do not read the full document top to bottom on the first pass. Read it in this order:
name, description, seller, price, customerSummary.status, payment, components, embeddedDocs.confirmOrder, attachPaymentToken, attachPayNote, attachComponentOrder.This order keeps the business story ahead of the contract mechanics.
Counter:
1increment entry2 -> operation3 -> Compute4 -> replace /counter5 -> emit event
Weekend package:
1checkout/payment/component/confirmation entries2 -> operations and embedded event channels3 -> Compute guards4 -> replace payment/component/status fields5 -> emit package, PayNote, and rejection events
The weekend package is not a different architecture. It is Counter with more state surfaces, more actors, and stronger guards.
That is why the docs should keep only these two examples. Counter teaches the loop. Weekend package proves the loop is worth learning.
The complete reseller package source is included here so the example can be read without leaving the docs. The first part is visible immediately; expand the rest when you want to inspect the full BEX and contract surface.
name: Romantic Weekend with a Premium Dinner for Two
description: A subsidized romantic weekend package from ITC / mega-pakiety.pl that combines a Hotel Badura stay with a Restaurant
Cud Malina dinner. Customer payment is secured first and completed only after both included orders are confirmed.
type: Common/Record
kind: Offer
offerKind: package
status: active
seller:
name: ITC / mega-pakiety.pl
price:
amountMinor: 49900
currency: PLN
customerSummary:
description: Payment is secured first and captured only after hotel and restaurant orders are confirmed.
headline: Romantic weekend with a premium dinner
included:
hotel:
description: Deluxe room for 2 people
title:
en: Weekend for 2 at Hotel Badura
pl: Weekend dla 2 osób w Hotelu Badura
localizedDescription:
en: Deluxe room for 2 people
pl: Pokój Deluxe dla 2 osób
fields:
- label:
en: Beds
pl: Łóżka
fieldType: text
fieldValue:
en: 1 large double bed
pl: 1 duże podwójne łóżko
- label:
en: Stay
pl: Pobyt
fieldType: text
fieldValue:
en: One-night weekend stay
pl: Jednonocny pobyt weekendowy
- label:
en: Meals
pl: Wyżywienie
fieldType: text
fieldValue:
en: Breakfast included
pl: Śniadanie w cenie
- label:
en: Check-in from
pl: Zameldowanie od
fieldType: time
fieldValue: '15:00'
- label:
en: Check-out until
pl: Wymeldowanie do
fieldType: time
fieldValue: '11:00'
- label:
en: Location
pl: Lokalizacja
fieldType: text
fieldValue:
en: Comfortable stay in a quiet area of Wadowice
pl: Komfortowy pobyt w spokojnej okolicy Wadowic
- label:
en: Address
pl: Adres
fieldType: text
fieldValue: Wenecja 4, 34-100 Wadowice
restaurant:
description: Premium romantic dinner for two at Cud Malina Restaurant
title:
en: Dinner at Cud Malina Restaurant
pl: Kolacja w Restauracji Cud Malina
localizedDescription:
en: Premium romantic dinner for two at Cud Malina Restaurant
pl: Romantyczna kolacja premium dla dwojga w Restauracji Cud Malina
fields:
- label:
en: Menu
pl: Menu
fieldType: plainText
fieldValue:
en: Starter, main course, and dessert selected from the menu, plus wine
pl: Przystawka, danie główne i deser wybrane z menu oraz wino
- label:
en: Address
pl: Adres
fieldType: plainText
fieldValue: Plac Tadeusza Kościuszki 22, 34-100 Wadowice
orderTemplate:
document:
name: Romantic Weekend with a Premium Dinner for Two Order
description: The customer's order for the Romantic Weekend with a Premium Dinner package. This order tracks checkout,
the included hotel and restaurant orders, and readiness to use.
type: Common/Record
kind: Package Order
status: awaiting_provider_confirmation
price:
amountMinor: 49900
currency: PLN
payment:
tokenAttached: false
payNoteAttached: false
state: not_started
paymentToken: ''
expectedPayNoteDescriptor: {}
checkoutMetadata: {}
components:
hotel:
title:
en: Weekend for 2 at Hotel Badura
pl: Weekend dla 2 osób w Hotelu Badura
status: not_started
orderAttached: false
restaurant:
title:
en: Dinner at Cud Malina Restaurant
pl: Kolacja w Restauracji Cud Malina
status: not_started
orderAttached: false
embeddedDocs:
orders: {}
contracts:
customerChannel:
type: MyOS/MyOS Timeline Channel
investorChannel:
type: MyOS/MyOS Timeline Channel
anchors:
type: MyOS/Document Anchors
payments:
name: Payments
type: MyOS/Document Anchor
links:
type: MyOS/Document Links
packageOffer:
type: MyOS/Document Link
anchor: orders
documentId: ''
embeddedPackagePayNoteEvents:
type: Core/Embedded Node Channel
childPath: /embeddedDocs/packagePayNote
processEmbeddedDocs:
type: Core/Process Embedded
paths:
- /embeddedDocs/packagePayNote
- /embeddedDocs/orders/hotelOrder
- /embeddedDocs/orders/restaurantOrder
markPaymentSecuredFromPayNoteEvent:
type: Coordination/Sequential Workflow
channel: embeddedPackagePayNoteEvents
event:
type: PayNote/Funds Secured
steps:
- name: BuildPaymentSecuredPatch
type: Coordination/Compute
emitEvents: true
do:
- $if:
cond:
$or:
- $eq:
- $document: /payment/state
- payment_secured
- $eq:
- $document: /payment/state
- completed
then:
- $return:
changeset:
$changeset: true
events:
$events: true
- $appendChange:
op: replace
path: /payment/state
val: payment_secured
- $return:
changeset:
$changeset: true
events:
$events: true
markReadyFromPayNoteCompletedEvent:
type: Coordination/Sequential Workflow
channel: embeddedPackagePayNoteEvents
event:
type: PayNote/Payment Completed
steps:
- name: BuildReadyPatch
type: Coordination/Compute
emitEvents: true
do:
- $if:
cond:
$and:
- $eq:
- $document: /status
- ready_to_use
- $eq:
- $document: /payment/state
- completed
then:
- $return:
changeset:
$changeset: true
events:
$events: true
- $appendChange:
op: replace
path: /status
val: ready_to_use
- $appendChange:
op: replace
path: /payment/state
val: completed
- $if:
cond:
$ne:
- $document: /status
- ready_to_use
then:
- $appendEvent:
type: Conversation/Event
kind: Package Ready To Use
orderKind: package
- $return:
changeset:
$changeset: true
events:
$events: true
overview:
type: Conversation/Document Section
relatedFields:
- /name
- /description
- /price
title: Package
paymentSafety:
type: Conversation/Document Section
relatedFields:
- /payment - /payment/checkoutMetadata
summary: Payment is secured first and captured only after hotel and restaurant orders are confirmed.
title: Secure checkout
includedOrders:
type: Conversation/Document Section
relatedFields:
- /embeddedDocs/orders/hotelOrder
- /embeddedDocs/orders/restaurantOrder
title: Included orders
statusSection:
type: Conversation/Document Section
relatedFields:
- /status
- /embeddedDocs/packagePayNote
title: Status
confirmOrder:
type: Coordination/Operation
description: Seller confirmation that this package order is accepted and checkout can be prepared.
channel: investorChannel
confirmOrderImpl:
type: Coordination/Sequential Workflow Operation
operation: confirmOrder
steps:
- name: BuildConfirmation
type: Coordination/Compute
emitEvents: true
do:
- $if:
cond:
$or:
- $eq:
- $document: /status
- provider_confirmed_pending_payment_token
- $eq:
- $document: /status
- provider_confirmed
- $eq:
- $document: /status
- ready_for_checkout
- $eq:
- $document: /status
- ready_to_use
then:
- $return:
changeset:
$changeset: true
events:
$events: true
- $appendChange:
op: replace
path: /status
val: provider_confirmed_pending_payment_token
- $appendEvent:
type: Conversation/Event
kind: Order Confirmed
orderKind: package
- $return:
changeset:
$changeset: true
events:
$events: true
attachPaymentToken:
type: Coordination/Operation
description: Attaches a one-time checkout token and PayNote descriptor prepared by ITC / mega-pakiety.pl.
channel: investorChannel
request:
paymentToken:
type: Text
expectedPayNoteDescriptor:
document:
name: Customer to ITC / mega-pakiety.pl Package PayNote
type: PayNote/PayNote
kind: PayNote
description: Customer package payment secured before provider orders.
payNoteInitialStateDescription:
summary: Payment for the Romantic Weekend with a Premium Dinner package.
details: 'This PayNote secures the customer''s package payment to ITC / mega-pakiety.pl. The payment is completed
only after both included merchant orders are confirmed: Hotel Badura confirms the weekend stay order and
Restaurant Cud Malina confirms the dinner order. Once both confirmations are present, the package payment
is completed and the package becomes ready to use.'
state:
type: Text
currency: PLN
amount:
expectedTotal: 49900
context:
scenario: reseller-weekend-package
paymentKind: customer_package_purchase
packageOrderDocumentId:
type: Text
packagePayNoteSessionId:
type: Text
packagePayNoteDocumentId:
type: Text
embeddedDocs:
orders: {}
completionRequested:
type: Boolean
contracts:
payerChannel:
type: MyOS/MyOS Timeline Channel
payeeChannel:
type: MyOS/MyOS Timeline Channel
guarantorChannel:
type: MyOS/MyOS Timeline Channel
links:
type: MyOS/Document Links
packageOrder:
type: MyOS/Document Link
documentId:
type: Text
anchor: payments
packageOffer:
type: MyOS/Document Link
documentId:
type: Text
anchor: customerPayNotes
embeddedHotelOrderEvents:
type: Core/Embedded Node Channel
childPath: /embeddedDocs/orders/hotelOrder
embeddedRestaurantOrderEvents:
type: Core/Embedded Node Channel
childPath: /embeddedDocs/orders/restaurantOrder
processEmbeddedComponentOrders:
type: Core/Process Embedded
paths:
- /embeddedDocs/orders/hotelOrder
- /embeddedDocs/orders/restaurantOrder
completeWhenOrdersConfirmedFromHotelEvent:
type: Coordination/Sequential Workflow
channel: embeddedHotelOrderEvents
event:
type: Conversation/Event
kind: Order Confirmed
steps:
- name: BuildCompletion
type: Coordination/Compute
emitEvents: true
do:
- $if:
cond:
$or:
- $ne:
- $document: /embeddedDocs/orders/hotelOrder/confirmation/status
- confirmed
- $ne:
- $document: /embeddedDocs/orders/restaurantOrder/confirmation/status
- confirmed
- $truthy:
$document: /completionRequested
then:
- $return:
changeset:
$changeset: true
events:
$events: true
- $appendChange:
op: replace
path: /completionRequested
val: true
- $appendEvent:
type: PayNote/Complete Payment Requested
amount: 49900
- $return:
changeset:
$changeset: true
events:
$events: true
completeWhenOrdersConfirmedFromRestaurantEvent:
type: Coordination/Sequential Workflow
channel: embeddedRestaurantOrderEvents
event:
type: Conversation/Event
kind: Order Confirmed
steps:
- name: BuildCompletion
type: Coordination/Compute
emitEvents: true
do:
- $if:
cond:
$or:
- $ne:
- $document: /embeddedDocs/orders/hotelOrder/confirmation/status
- confirmed
- $ne:
- $document: /embeddedDocs/orders/restaurantOrder/confirmation/status
- confirmed
- $truthy:
$document: /completionRequested
then:
- $return:
changeset:
$changeset: true
events:
$events: true
- $appendChange:
op: replace
path: /completionRequested
val: true
- $appendEvent:
type: PayNote/Complete Payment Requested
amount: 49900
- $return:
changeset:
$changeset: true
events:
$events: true
attachComponentOrder:
type: Coordination/Operation
description: Attaches an included merchant order snapshot so package payment can complete after both confirmations.
channel: payeeChannel
request:
kind:
type: Text
initialSnapshot:
type: Common/Record
kind: Order
orderKind:
type: Text
status:
type: Text
context:
packageOrderDocumentId:
type: Text
orderSessionId:
type: Text
orderDetails:
type: Dictionary
payment:
tokenAttached:
type: Boolean
paymentToken:
type: Text
confirmation:
status:
type: Text
fulfillment:
status:
type: Text
contracts:
type: Dictionary
attachComponentOrderImpl:
type: Coordination/Sequential Workflow Operation
operation: attachComponentOrder
steps:
- name: BuildComponentAttachment
type: Coordination/Compute
emitEvents: true
do:
- $if:
cond:
$and:
- $and:
- $eq:
- $event: /message/request/kind
- hotel
- $eq:
- $event: /message/request/initialSnapshot/kind
- Order
- $eq:
- $event: /message/request/initialSnapshot/orderKind
- hotel
- $eq:
- $event: /message/request/initialSnapshot/context/packageOrderDocumentId
- $document: /context/packageOrderDocumentId
then:
- $appendChange:
op: add
path: /embeddedDocs/orders/hotelOrder
val:
$event: /message/request/initialSnapshot
- $appendEvent:
type: Conversation/Event
kind: Component Order Attached
orderKind: hotel
- $return:
changeset:
$changeset: true
events:
$events: true
- $if:
cond:
$and:
- $and:
- $eq:
- $event: /message/request/kind
- restaurant
- $eq:
- $event: /message/request/initialSnapshot/kind
- Order
- $eq:
- $event: /message/request/initialSnapshot/orderKind
- restaurant
- $eq:
- $event: /message/request/initialSnapshot/context/packageOrderDocumentId
- $document: /context/packageOrderDocumentId
then:
- $appendChange:
op: add
path: /embeddedDocs/orders/restaurantOrder
val:
$event: /message/request/initialSnapshot
- $appendEvent:
type: Conversation/Event
kind: Component Order Attached
orderKind: restaurant
- $return:
changeset:
$changeset: true
events:
$events: true
- $appendEvent:
type: Conversation/Event
kind: Component Order Attachment Rejected
orderKind:
$event: /message/request/kind
- $return:
changeset:
$changeset: true
events:
$events: true
channelBindings:
payerChannel:
type: MyOS/MyOS Timeline Channel
accountId:
type: Text
payeeChannel:
type: MyOS/MyOS Timeline Channel
accountId:
type: Text
guarantorChannel:
type: MyOS/MyOS Timeline Channel
accountId: '0'
checkoutMetadata:
type: Dictionary
attachPaymentTokenImpl:
type: Coordination/Sequential Workflow Operation
operation: attachPaymentToken
steps:
- name: BuildPaymentTokenPatch
type: Coordination/Compute
emitEvents: true
do:
- $if:
cond:
$eq:
- $document: /payment/tokenAttached
- true
then:
- $return:
changeset:
$changeset: true
events:
$events: true
- $if:
cond:
$or:
- $and:
- $ne:
- $document: /status
- provider_confirmed_pending_payment_token
- $ne:
- $document: /status
- provider_confirmed
- $not:
$truthy:
$event: /message/request/paymentToken
- $not:
$truthy:
$event: /message/request/expectedPayNoteDescriptor/document
then:
- $appendEvent:
type: Conversation/Event
kind: Payment Token Attachment Rejected
reason: provider_not_confirmed_or_missing_checkout_payload
- $return:
changeset:
$changeset: true
events:
$events: true
- $appendChange:
op: replace
path: /payment/tokenAttached
val: true
- $appendChange:
op: replace
path: /payment/paymentToken
val:
$event: /message/request/paymentToken
- $appendChange:
op: replace
path: /payment/expectedPayNoteDescriptor
val:
$event: /message/request/expectedPayNoteDescriptor
- $appendChange:
op: replace
path: /payment/checkoutMetadata
val:
$default:
- $event: /message/request/checkoutMetadata
- $emptyObject: true
- $appendChange:
op: replace
path: /status
val: ready_for_checkout
- $appendEvent:
type: Conversation/Event
kind: Payment Token Attached
orderKind: package
- $return:
changeset:
$changeset: true
events:
$events: true
attachPayNote:
type: Coordination/Operation
description: Attaches the secured customer package PayNote discovered through the order's payments anchor.
channel: investorChannel
request:
initialSnapshot:
kind: PayNote
attachPayNoteImpl:
type: Coordination/Sequential Workflow Operation
operation: attachPayNote
steps:
- name: BuildPayNoteAttachment
type: Coordination/Compute
emitEvents: true
do:
- $if:
cond:
$or:
- $ne:
- $event: /message/request/initialSnapshot/kind
- PayNote
- $ne:
- $event: /message/request/initialSnapshot/context/paymentKind
- customer_package_purchase
- $not:
$truthy:
$document: /contracts/initialized/documentId
- $ne:
- $event: /message/request/initialSnapshot/context/packageOrderDocumentId
- $document: /contracts/initialized/documentId
then:
- $appendEvent:
type: Conversation/Event
kind: PayNote Attachment Rejected
reason: invalid_paynote_snapshot
- $return:
changeset:
$changeset: true
events:
$events: true
- $if:
cond:
$eq:
- $document: /payment/payNoteAttached
- true
then:
- $appendEvent:
type: Conversation/Event
kind: PayNote Attachment Rejected
reason: paynote_already_attached
- $return:
changeset:
$changeset: true
events:
$events: true
- $appendChange:
op: add
path: /embeddedDocs/packagePayNote
val:
$event: /message/request/initialSnapshot
- $appendChange:
op: replace
path: /payment/payNoteAttached
val: true
- $if:
cond:
$and:
- $ne:
- $document: /payment/state
- completed
- $ne:
- $document: /payment/state
- payment_secured
- $ne:
- $document: /payment/state
- paynote_attached
then:
- $appendChange:
op: replace
path: /payment/state
val: paynote_attached
- $return:
changeset:
$changeset: true
events:
$events: true
attachComponentOrder:
type: Coordination/Operation
description: Attaches an initial snapshot of one included merchant order to this package order.
channel: investorChannel
request:
kind:
type: Text
initialSnapshot:
kind: Order
attachComponentOrderImpl:
type: Coordination/Sequential Workflow Operation
operation: attachComponentOrder
steps:
- name: BuildComponentAttachment
type: Coordination/Compute
emitEvents: true
do:
- $if:
cond:
$and:
- $eq:
- $event: /message/request/kind
- hotel
- $eq:
- $event: /message/request/initialSnapshot/kind
- Order
- $eq:
- $event: /message/request/initialSnapshot/orderKind
- hotel
then:
- $appendChange:
op: add
path: /embeddedDocs/orders/hotelOrder
val:
$event: /message/request/initialSnapshot
- $appendChange:
op: replace
path: /components/hotel/orderAttached
val: true
- $appendChange:
op: replace
path: /components/hotel/status
val: order_attached
- $appendEvent:
type: Conversation/Event
kind: Component Order Attached
orderKind: hotel
orderSessionId:
$event: /message/request/initialSnapshot/context/orderSessionId
- $return:
changeset:
$changeset: true
events:
$events: true
- $if:
cond:
$and:
- $eq:
- $event: /message/request/kind
- restaurant
- $eq:
- $event: /message/request/initialSnapshot/kind
- Order
- $eq:
- $event: /message/request/initialSnapshot/orderKind
- restaurant
then:
- $appendChange:
op: add
path: /embeddedDocs/orders/restaurantOrder
val:
$event: /message/request/initialSnapshot
- $appendChange:
op: replace
path: /components/restaurant/orderAttached
val: true
- $appendChange:
op: replace
path: /components/restaurant/status
val: order_attached
- $appendEvent:
type: Conversation/Event
kind: Component Order Attached
orderKind: restaurant
orderSessionId:
$event: /message/request/initialSnapshot/context/orderSessionId
- $return:
changeset:
$changeset: true
events:
$events: true
- $appendEvent:
type: Conversation/Event
kind: Component Order Attachment Rejected
orderKind:
$event: /message/request/kind
- $return:
changeset:
$changeset: true
events:
$events: true
contracts:
anchors:
type: MyOS/Document Anchors
orders:
name: Orders
type: MyOS/Document Anchor
customerPayNotes:
name: Customer PayNotes
type: MyOS/Document Anchor
investorChannel:
type: MyOS/MyOS Timeline Channel
initLifecycleChannel:
type: Core/Lifecycle Event Channel
event:
type: Core/Document Processing Initiated
initializeOrderTemplateSourceOfferLink:
type: Coordination/Sequential Workflow
channel: initLifecycleChannel
steps:
- name: BuildOrderTemplateLinkPatch
type: Coordination/Compute
emitEvents: true
do:
- $if:
cond:
$or:
- $not:
$truthy:
$document: /contracts/initialized/documentId
- $eq:
- $document: /orderTemplate/document/contracts/links/packageOffer/documentId
- $document: /contracts/initialized/documentId
then:
- $return:
changeset:
$changeset: true
events:
$events: true
- $appendChange:
op: replace
path: /orderTemplate/document/contracts/links/packageOffer/documentId
val:
$document: /contracts/initialized/documentId
- $return:
changeset:
$changeset: true
events:
$events: true
packageSection:
type: Conversation/Document Section
relatedFields:
- /name
- /description
- /seller
- /price
title: Package summary
includedSection:
type: Conversation/Document Section
relatedFields:
- /customerSummary/included
title: Included experiences
checkoutSection:
type: Conversation/Document Section
relatedFields:
- /customerSummary
- /orderTemplate
title: Secure checkout