# PaymentSummary

The `PaymentSummary` component is a crucial UI element for any checkout process. It provides a detailed breakdown of the order, including all line items, trial period information, staking requirements, and the final total amount. It's designed to be responsive and adapts its layout for mobile devices.

This component works in tandem with `ProductItem` and `ProductDonation` to render each item in the cart, and it handles user interactions like applying cross-sells or changing quantities.

## Props

The `PaymentSummary` component accepts the following props to customize its behavior and display:

| Prop | Type | Required | Description |
| --- | --- | --- | --- |
| `items` | `TLineItemExpanded[]` | Yes | An array of line items to be displayed in the summary. |
| `currency` | `TPaymentCurrency` | Yes | The currency object for formatting amounts. |
| `trialInDays` | `number` | Yes | The number of trial days for recurring subscriptions. |
| `billingThreshold` | `number` | Yes | The billing threshold amount. Used in staking calculation if applicable. |
| `trialEnd` | `number` | No | A Unix timestamp for when the trial ends. Overrides `trialInDays`. |
| `showStaking` | `boolean` | No | If `true`, displays staking details. Defaults to `false`. |
| `onUpsell` | `(from: string, to: string) => void` | No | Callback function when a user accepts an upsell offer. |
| `onDownsell` | `(from: string) => void` | No | Callback function when a user reverts an upsell offer. |
| `onQuantityChange` | `(itemId: string, quantity: number) => void` | No | Callback function when the quantity of an item is changed. |
| `onChangeAmount` | `(itemId: string, amount: string) => void` | No | Callback for changing the amount of a custom-amount item, like a donation. |
| `onApplyCrossSell` | `(crossSellId: string) => void` | No | Callback function when a user adds a cross-sell item. |
| `onCancelCrossSell` | `() => void` | No | Callback function when a user removes a cross-sell item. |
| `checkoutSessionId` | `string` | No | The ID of the checkout session, used to fetch potential cross-sell items. |
| `crossSellBehavior` | `string` | No | Defines the behavior of the cross-sell item (e.g., `'required'`). |
| `donationSettings` | `DonationSettings` | No | Configuration for donation items. |
| `action` | `string` | No | A custom title for the summary section, replacing "Order Summary". |
| `completed` | `boolean` | No | If `true`, disables interactive elements like quantity adjustment. Defaults to `false`. |

## Usage

The `PaymentSummary` component should be placed within a `PaymentProvider` and is typically used as part of a larger checkout form. You need to provide it with the line items and currency information.

Here is a basic example of how to integrate the `PaymentSummary` component.

```tsx PaymentSummary Example icon=lucide:shopping-cart
import React from 'react';
import { PaymentProvider, PaymentSummary } from '@blocklet/payment-react';
import { useSessionContext } from '../hooks/session-context'; // Your session context hook

// Mock data for demonstration purposes
const mockCurrency = {
  id: 'usd_4573516104843264',
  symbol: '$',
  name: 'USD',
  decimal: 2,
  isDefault: true,
};

const mockItems = [
  {
    id: 'li_1',
    price_id: 'price_1',
    quantity: 1,
    adjustable_quantity: { enabled: true, minimum: 1, maximum: 10 },
    price: {
      id: 'price_1',
      type: 'recurring',
      recurring: { interval: 'month', interval_count: 1, usage_type: 'licensed' },
      unit_amount: '2000',
      product: {
        name: 'Pro Plan',
        images: [],
      },
    },
  },
];

export default function MyCheckoutPage() {
  const { session, connectApi } = useSessionContext();

  const handleQuantityChange = (itemId, newQuantity) => {
    console.log(`Item ${itemId} quantity changed to ${newQuantity}`);
    // Here you would typically update your state and refetch checkout info
  };

  return (
    <PaymentProvider session={session} connectApi={connectApi}>
      <PaymentSummary
        items={mockItems}
        currency={mockCurrency}
        trialInDays={14}
        billingThreshold={0}
        showStaking={true}
        onQuantityChange={handleQuantityChange}
      />
    </PaymentProvider>
  );
}
```

### Displaying Staking and Totals

If `showStaking` is set to `true`, the component will calculate and display the required staking amount for recurring items. It separates the amount due for immediate payment from the amount required for staking, providing a clear financial summary to the user. The final total combines these amounts.

### Handling Trial Periods

The component clearly communicates trial periods to the user. By passing `trialInDays` or `trialEnd`, a message like "Then $20.00 / month" will be displayed below the total, informing the user about the recurring charges after the trial concludes.

### Interactive Features

- **Quantity Adjustment**: If an item has `adjustable_quantity.enabled` set to `true`, the `PaymentSummary` (via its child `ProductItem`) will render controls to increase or decrease the quantity. The `onQuantityChange` callback is triggered upon modification.
- **Upsell/Downsell**: For products with an upsell configuration, a switch is rendered to allow users to upgrade their plan. The `onUpsell` and `onDownsell` callbacks handle these actions.
- **Cross-Sell**: If a `checkoutSessionId` is provided, the component can fetch and display suggested cross-sell items. Buttons to add or remove these items trigger the `onApplyCrossSell` and `onCancelCrossSell` callbacks.

### Mobile Responsiveness

On mobile devices, the list of products is collapsible by default to save space, especially for orders with many items. Users can tap to expand or collapse the list, providing a cleaner and more user-friendly experience on smaller screens.