
import PurchaseFields from "../../../src/reference/subbly-sdk/types/CheckoutPurchaseResponse.mdx";

<SdkPage group="checkout" />

<Method id="purchase" signature="subbly.checkout.purchase(cartId, payload?, params?)">

Charges the cart and creates the subscription, the invoice and the orders. It
needs a signed-in customer, and the cart must be ready: a customer attached, a
delivery method set and a payment method chosen.

The SDK does not touch `subbly.cart` afterwards. The cart is complete on the
server, so drop your local copy and create a new one for the next order.

A card that needs 3-D Secure rejects with `code: 'payment_requires_action'` and
a `paymentIntentId`. Take the customer through the verification with
`subbly.paymentIntents.getPaymentIntent` and
`subbly.paymentIntents.confirm`, then call `purchase` again with the same
`paymentIntentId`. The call can also reject with `out_of_stock` or
`bad_request`.

<Params>
  <Param name="cartId" required type="string">
  UUID of the cart to charge, usually `subbly.cart.id`.
  </Param>
  <Param name="payload" optional type="CheckoutPurchasePayload">
    How to pay. Leave it out to charge the payment method already on the cart.

    <Properties label="payload">
      <Param name="paymentMethodId" optional type="number">
      Payment method to charge, from `subbly.wallet.list`. Falls back to
      `cart.paymentMethodId`.
      </Param>
      <Param name="paymentIntentId" optional type="string | null">
      The payment intent the customer just verified. Send it when you retry
      after 3-D Secure.
      </Param>
    </Properties>
  </Param>
  <Param name="params" optional type="PurchaseRequestParams">
    Relations to include in the response.

    <Properties label="params">
      <Param name="expand" optional type="string[]">
      `subscription.product`, `subscription.product.parent`,
      `subscription.product.parent.bundle`, `subscription.metadata`,
      `order.metadata`, `order.items.metadata`, `invoice.metadata` and
      `invoice.items.metadata`.
      </Param>
    </Properties>
  </Param>
</Params>

<Returns type="Promise<CheckoutPurchaseResponse>">
What the purchase created.
<Properties label="response" collapsed>
  <PurchaseFields />
</Properties>
</Returns>

<Example>

```js title="Purchase the cart"
const { invoice, subscription, orders } = await subbly.checkout.purchase(
  subbly.cart.id,
)
```

```js title="Handle 3-D Secure"
try {
  await subbly.checkout.purchase(subbly.cart.id)
} catch (error) {
  if (error.code !== 'payment_requires_action') throw error

  const intent = await subbly.paymentIntents.getPaymentIntent(
    error.paymentIntentId,
  )

  // Verify `intent.token` with the payment gateway, then:
  await subbly.paymentIntents.confirm(intent.id, externalPaymentId)
  await subbly.checkout.purchase(subbly.cart.id, {
    paymentIntentId: intent.id,
  })
}
```

</Example>

</Method>
