diff --git a/src/app/connect/pay/accept-direct-payments/page.mdx b/src/app/connect/pay/accept-direct-payments/page.mdx
new file mode 100644
index 00000000..bf5428d8
--- /dev/null
+++ b/src/app/connect/pay/accept-direct-payments/page.mdx
@@ -0,0 +1,103 @@
+import { createMetadata, Callout, DocImage, Steps, Step } from "@doc";
+import DirectPaymentsFlow from "../assets/direct-payments-flow.png";
+
+export const metadata = createMetadata({
+ image: {
+ title: "thirdweb Pay - Accept Direct Payments",
+ icon: "thirdweb",
+ },
+ title: "thirdweb Pay - Accept Direct Payments | thirdweb",
+ description:
+ "Combine Pay and Engine to create a smooth point of sale experience on any chain",
+});
+
+# Accept Direct Payments with Pay & Engine
+
+Learn how to accept fiat and crypto from your customers with Pay and trigger Engine actions, like minting NFTs or transferring tokens to user wallets.
+
+### Requirements
+
+- [A thirdweb Client ID](https://thirdweb.com/dashboard/settings/api-keys)
+- [An Engine Instance](https://thirdweb.com/dashboard/engine)
+
+### Purchase Flow Overview
+
+Before jumping in, it's important to understand the full system, from initial purchase to the eventual transfer of assets. This is a four step process (with an optional fifth):
+
+
+
+1. **User Initiates Purchase:** User sends specified funds (ETH, MATIC, USD, etc.) to your backend wallet via thirdweb Pay. Use the `purchaseData` field to pass any item data needed in the webhook.
+ E.g., `{ nftId: 1 }`.
+2. **Pay Processes Purchase:** thirdweb Pay processes the transaction and sends a [Purchase Complete webhook](/connect/pay/webhooks#purchase-complete) to your dapp’s server when the transaction is complete.
+3. **Your Server Calls Engine:** Your server processes the webhook and sends a contract call to the thirdweb Engine backend wallet to perform the item purchase.
+4. **Engine Executes the Transaction:** Engine backend wallet executes the transaction needed to deliver the token(s) to the user’s address.
+5. **(Optional) User Is Notified :** Your server confirms the completed Engine transaction and notifies the user.
+
+Now, let's get started.
+
+
+
+
+ 1. If you haven't already, [deploy an Engine
+ instance](https://thirdweb.com/dashboard/engine)
+
+ 2. Create or import a backend wallet for Engine in [your Engine dashboard](https://thirdweb.com/dashboard/engine).
+
+ 3. Send the required funds to the backend wallet
+ * For example, if purchasing with Arb Nova USDC, then your backend wallet should hold this ERC20 token.
+ * If your backend wallet holds an ERC20 token, ensure to add a native token balance as well to cover gas costs. For example, for a transaction on Arbitrum Nova, your backend wallet should hold both Arb Nova USDC (for payment) and Arb Nova ETH (for gas).
+ * Your backend wallet should hold enough liquidity to handle any anticipated purchasing volume.
+
+ 4. Make a plan to monitor and keep the float wallet topped up to avoid any issues with the service.
+
+
+ 1. [Integrate thirdweb Pay](https://portal.thirdweb.com/connect/pay/build-a-custom-experience) on the client side to enable fiat and crypto payments.
+
+
+ 2. Specify the required parameters for your Pay transaction.
+
+ ```ts
+ const quote = await getBuyWithFiatQuote({
+ client: client, // thirdweb client
+ fromCurrencySymbol: "USD", // fiat currency symbol
+ toChainId: arbnova.id, // arbitrum nova chain id
+ toAmount: "100", // amount of token to buy
+ toTokenAddress: USDC_TOKEN_ADDRESS, // address of payment token
+ fromAddress: "",
+ toAddress: "",
+ purchaseData: {
+ nftId: 1
+ }
+ });
+ ```
+
+ |Parameter|Type|Description|
+ |----|--|--|
+ |fromCurrencySymbol|`string`|The fiat currency symbol you'd like to accept (currently limited to USD and EUR) |
+ |toChainId|`string`|[Chain ID](https://thirdweb.com/chainlist) for the destination token.|
+ |toTokenAddress|`string`|Address of the destination token.|
+ |toAmount|`string`|The price of the asset denominated in your desination token.|
+ |fromAddress|`string`|The user's wallet address.|
+ |toAddress|`string`|The wallet you'd like funds to be sent to. This can be your business wallet or an Engine backend wallet. |
+ |purchaseData|`Object`|Any details you need to pass in order to track your transaction. If this is a secondary sale, you may want to include details like `{ nftId: 1, orderId: 1 }` |
+
+
+
+ 1. Create a “Purchase Complete” webhook in [the Pay dashboard](https://thirdweb.com/dashboard/connect/pay).
+ 2. The [Pay webhook POST response](/connect/pay/webhooks#purchase-complete) will include the BuyWithCryptoStatus or BuyWithFiatStatus in the body.
+ * This will also include the purchaseData you previously passed (metadata identifying the customer information, etc.).
+ * A request will be sent on every status change.
+ 3. Listen for [completed purchase statuses](https://portal.thirdweb.com/connect/pay/build-a-custom-experience#Poll%20for%20Transaction%20Status).
+ * Note, if this is a two-step BuyWithFiat transaction (onramp, then swap), you should also listen for `CRYPTO_SWAP_COMPLETED`
+ 4. When a purchase is completed, determine the purchaser, order and validate the amounts.
+ - The fromAddress in the status will show purchasing address
+ - The purchaseData will contain more information you previously for the purchase details
+ - Validate the information. For example, 100 USDC was sent to your wallet.
+ 5. Send a contract call to Engine for the float wallet to purchase the item
+ - For example, send a transaction to the float wallet for `mintTo(fromAddress)`
+ - For secondary purchases, like a marketplace direct listing, you can use the appropriate Engine endpoint, passing the ultimate recipient of the NFT as the buyer
+ 6. Confirm the purchase was successful.
+
+
+
+Once you've completed all of these steps, you'll be ready to offer a great purchase UX for your users.
diff --git a/src/app/connect/pay/assets/direct-payments-flow.png b/src/app/connect/pay/assets/direct-payments-flow.png
new file mode 100644
index 00000000..47bdc1bd
Binary files /dev/null and b/src/app/connect/pay/assets/direct-payments-flow.png differ
diff --git a/src/app/connect/pay/webhooks/page.mdx b/src/app/connect/pay/webhooks/page.mdx
new file mode 100644
index 00000000..debbfc8d
--- /dev/null
+++ b/src/app/connect/pay/webhooks/page.mdx
@@ -0,0 +1,182 @@
+import { createMetadata, DocImage } from "@doc";
+import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs";
+
+export const metadata = createMetadata({
+ title: "Webhooks | thirdweb Pay",
+ description:
+ "Configure Pay webhooks to get notified at any point during a transaction's lifecycle.",
+});
+
+# Webhooks
+
+Pay can be configured to send webhook events to notify your application any time an event happens on your transaction. Pay sends a response, via a HTTP request, to any endpoint URLs that you have provided us in [the Pay dashboard](https://thirdweb.com/dashboard/connect/pay).
+
+## Events
+
+To listen to events, create a webhook in [the Pay dashboard](https://thirdweb.com/dashboard/connect/pay). Webhook URLs must start with `https://`.
+
+| Event | Description |
+| ------------------- | ----------------------------------- |
+| `purchase_complete` | A transaction is confirmed onchain. |
+
+### Purchase Complete
+
+Triggered when a transaction is confirmed onchain. This event provides information about the new status of the order and its transactionHash, as well as other relevant information.
+
+Example Response:
+
+
+
+
+ Fiat Purchase
+ Crypto Purchase
+
+
+
+```json
+{
+ "data": {
+ "buyWithFiatStatus": {
+ "intentId": "f4cf8ab7-bb62-4b3b-a180-70fc7d72446c",
+ "status": "ON_RAMP_TRANSFER_COMPLETED",
+ "toAddress": "0xebfb127320fcbe8e07e5a03a4bfb782219f4735b",
+ "quote": {
+ "createdAt": "2024-06-18T23:46:46.024Z",
+ "fromCurrency": {
+ "amountUnits": "279",
+ "amount": "2.79",
+ "currencySymbol": "USD",
+ "decimals": 2,
+ "amountUSDCents": 279
+ },
+ "fromCurrencyWithFees": {
+ "amountUnits": "294",
+ "amount": "2.94",
+ "currencySymbol": "USD",
+ "decimals": 2,
+ "amountUSDCents": 279
+ },
+ "onRampToken": {
+ "chainId": 137,
+ "tokenAddress": "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
+ "name": "Matic",
+ "symbol": "MATIC",
+ "decimals": 18,
+ "priceUSDCents": 54.797200000000004
+ },
+ "toToken": {
+ "chainId": 137,
+ "tokenAddress": "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
+ "name": "Matic",
+ "symbol": "MATIC",
+ "decimals": 18,
+ "priceUSDCents": 54.797200000000004
+ },
+ "estimatedOnRampAmountWei": "5000000000000000000",
+ "estimatedOnRampAmount": "5",
+ "estimatedToTokenAmount": "5",
+ "estimatedToTokenAmountWei": "5000000000000000000",
+ "estimatedDurationSeconds": 30
+ },
+ "source": {
+ "completedAt": "2024-06-18T23:49:00.347Z",
+ "amount": "5",
+ "amountWei": "5000000000000000000",
+ "token": {
+ "chainId": 137,
+ "tokenAddress": "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
+ "name": "Matic",
+ "symbol": "MATIC",
+ "decimals": 18,
+ "priceUSDCents": 54.797200000000004
+ },
+ "transactionHash": "0x4bb089f6a60b49235a817b52bf39bc078f1246df15731b85837526bb62cf4e70",
+ "explorerLink": "https://polygonscan.com/tx/0x4bb089f6a60b49235a817b52bf39bc078f1246df15731b85837526bb62cf4e70",
+ "amountUSDCents": 275
+ }
+ }
+ }
+}
+```
+
+
+
+```json
+{
+ "data": {
+ "buyWithCryptoStatus": {
+ "swapType": "SAME_CHAIN",
+ "source": {
+ "transactionHash": "0x74d6c619a09e78f03f4bd495f29d5937a2539d0bbe8973e7710dce3e88c30b8b",
+ "token": {
+ "chainId": 10,
+ "tokenAddress": "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
+ "decimals": 18,
+ "name": "ETH",
+ "symbol": "ETH",
+ "priceUSDCents": 346529
+ },
+ "amountWei": "318486512146714",
+ "amount": "0.000318486512146714",
+ "amountUSDCents": 110,
+ "completedAt": "2024-06-18T23:44:07.000Z"
+ },
+ "status": "COMPLETED",
+ "subStatus": "SUCCESS",
+ "fromAddress": "0xebfb127320fcbe8e07e5a03a4bfb782219f4735b",
+ "toAddress": "0xebfb127320fcbe8e07e5a03a4bfb782219f4735b",
+ "quote": {
+ "fromToken": {
+ "chainId": 10,
+ "tokenAddress": "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
+ "decimals": 18,
+ "name": "ETH",
+ "symbol": "ETH",
+ "priceUSDCents": 346529
+ },
+ "toToken": {
+ "chainId": 10,
+ "tokenAddress": "0x0b2c639c533813f4aa9d7837caf62653d097ff85",
+ "decimals": 6,
+ "name": "USD Coin",
+ "symbol": "USDC",
+ "priceUSDCents": 99
+ },
+ "fromAmountWei": "318486512146714",
+ "fromAmount": "0.000318486512146714",
+ "toAmountWei": "1100000",
+ "toAmount": "1.1",
+ "toAmountMinWei": "1100000",
+ "toAmountMin": "1.1",
+ "estimated": {
+ "fromAmountUSDCents": 110,
+ "toAmountMinUSDCents": 109,
+ "toAmountUSDCents": 109,
+ "slippageBPS": 91,
+ "feesUSDCents": 32,
+ "gasCostUSDCents": 40,
+ "durationSeconds": 30
+ },
+ "createdAt": "2024-06-18T23:43:45.900Z"
+ },
+ "destination": {
+ "transactionHash": "0x74d6c619a09e78f03f4bd495f29d5937a2539d0bbe8973e7710dce3e88c30b8b",
+ "token": {
+ "chainId": 10,
+ "tokenAddress": "0x0b2c639c533813f4aa9d7837caf62653d097ff85",
+ "decimals": 6,
+ "name": "USD Coin",
+ "symbol": "USDC",
+ "priceUSDCents": 99
+ },
+ "amountWei": "1100000",
+ "amount": "1.1",
+ "amountUSDCents": 109,
+ "completedAt": "2024-06-18T23:44:07.000Z"
+ }
+ }
+ }
+}
+```
+
+
diff --git a/src/app/connect/sidebar.tsx b/src/app/connect/sidebar.tsx
index 8c6655bc..1af5d64e 100644
--- a/src/app/connect/sidebar.tsx
+++ b/src/app/connect/sidebar.tsx
@@ -482,6 +482,10 @@ export const sidebar: SideBar = {
},
],
},
+ {
+ name: "Webhooks",
+ href: `${paySlug}/webhooks`,
+ },
{
name: "Enable Test Mode",
href: `${paySlug}/test-mode`,
@@ -490,6 +494,10 @@ export const sidebar: SideBar = {
name: "Build a Custom Experience",
href: `${paySlug}/build-a-custom-experience`,
},
+ {
+ name: "Accept Direct Payments",
+ href: `${paySlug}/accept-direct-payments`,
+ },
{
name: "FAQs",
href: `${paySlug}/faqs`,