|
| 1 | +import { createMetadata, Callout, DocImage, Steps, Step } from "@doc"; |
| 2 | +import DirectPaymentsFlow from "../assets/direct-payments-flow.png"; |
| 3 | + |
| 4 | +export const metadata = createMetadata({ |
| 5 | + image: { |
| 6 | + title: "thirdweb Pay - Accept Direct Payments", |
| 7 | + icon: "thirdweb", |
| 8 | + }, |
| 9 | + title: "thirdweb Pay - Accept Direct Payments | thirdweb", |
| 10 | + description: |
| 11 | + "Combine Pay and Engine to create a smooth point of sale experience on any chain", |
| 12 | +}); |
| 13 | + |
| 14 | +# Accept Direct Payments with Pay & Engine |
| 15 | + |
| 16 | +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. |
| 17 | + |
| 18 | +### Requirements |
| 19 | + |
| 20 | +- [A thirdweb Client ID](https://thirdweb.com/dashboard/settings/api-keys) |
| 21 | +- [An Engine Instance](https://thirdweb.com/dashboard/engine) |
| 22 | + |
| 23 | +### Purchase Flow Overview |
| 24 | + |
| 25 | +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): |
| 26 | + |
| 27 | +<DocImage src={DirectPaymentsFlow} /> |
| 28 | + |
| 29 | +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. |
| 30 | + E.g., `{ nftId: 1 }`. |
| 31 | +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. |
| 32 | +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. |
| 33 | +4. **Engine Executes the Transaction:** Engine backend wallet executes the transaction needed to deliver the token(s) to the user’s address. |
| 34 | +5. **(Optional) User Is Notified :** Your server confirms the completed Engine transaction and notifies the user. |
| 35 | + |
| 36 | +Now, let's get started. |
| 37 | + |
| 38 | +<Steps> |
| 39 | + <Step title="Set Up Thirdweb Engine"> |
| 40 | + |
| 41 | + 1. If you haven't already, [deploy an Engine |
| 42 | + instance](https://thirdweb.com/dashboard/engine) |
| 43 | + |
| 44 | + 2. Create or import a backend wallet for Engine in [your Engine dashboard](https://thirdweb.com/dashboard/engine). |
| 45 | + |
| 46 | + 3. Send the required funds to the backend wallet |
| 47 | + * For example, if purchasing with Arb Nova USDC, then your backend wallet should hold this ERC20 token. |
| 48 | + * 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). |
| 49 | + * Your backend wallet should hold enough liquidity to handle any anticipated purchasing volume. |
| 50 | + |
| 51 | + 4. Make a plan to monitor and keep the float wallet topped up to avoid any issues with the service. |
| 52 | + </Step> |
| 53 | + <Step title="Integrate thirdweb Pay (Client)"> |
| 54 | + 1. [Integrate thirdweb Pay](https://portal.thirdweb.com/connect/pay/build-a-custom-experience) on the client side to enable fiat and crypto payments. |
| 55 | + |
| 56 | + |
| 57 | + 2. Specify the required parameters for your Pay transaction. |
| 58 | + |
| 59 | + ```ts |
| 60 | + const quote = await getBuyWithFiatQuote({ |
| 61 | + client: client, // thirdweb client |
| 62 | + fromCurrencySymbol: "USD", // fiat currency symbol |
| 63 | + toChainId: arbnova.id, // arbitrum nova chain id |
| 64 | + toAmount: "100", // amount of token to buy |
| 65 | + toTokenAddress: USDC_TOKEN_ADDRESS, // address of payment token |
| 66 | + fromAddress: "<USERS_WALLET_ADDRESS>", |
| 67 | + toAddress: "<YOUR_WALLET_ADDRESS>", |
| 68 | + purchaseData: { |
| 69 | + nftId: 1 |
| 70 | + } |
| 71 | + }); |
| 72 | + ``` |
| 73 | + |
| 74 | + |Parameter|Type|Description| |
| 75 | + |----|--|--| |
| 76 | + |fromCurrencySymbol|`string`|The fiat currency symbol you'd like to accept (currently limited to USD and EUR) | |
| 77 | + |toChainId|`string`|[Chain ID](https://thirdweb.com/chainlist) for the destination token.| |
| 78 | + |toTokenAddress|`string`|Address of the destination token.| |
| 79 | + |toAmount|`string`|The price of the asset denominated in your desination token.| |
| 80 | + |fromAddress|`string`|The user's wallet address.| |
| 81 | + |toAddress|`string`|The wallet you'd like funds to be sent to. This can be your business wallet or an Engine backend wallet. | |
| 82 | + |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 }` | |
| 83 | + |
| 84 | +</Step> |
| 85 | + <Step title="Integrate thirdweb Pay (Server)"> |
| 86 | + 1. Create a “Purchase Complete” webhook in [the Pay dashboard](https://thirdweb.com/dashboard/connect/pay). |
| 87 | + 2. The [Pay webhook POST response](/connect/pay/webhooks#purchase-complete) will include the BuyWithCryptoStatus or BuyWithFiatStatus in the body. |
| 88 | + * This will also include the purchaseData you previously passed (metadata identifying the customer information, etc.). |
| 89 | + * A request will be sent on every status change. |
| 90 | + 3. Listen for [completed purchase statuses](https://portal.thirdweb.com/connect/pay/build-a-custom-experience#Poll%20for%20Transaction%20Status). |
| 91 | + * Note, if this is a two-step BuyWithFiat transaction (onramp, then swap), you should also listen for `CRYPTO_SWAP_COMPLETED` |
| 92 | + 4. When a purchase is completed, determine the purchaser, order and validate the amounts. |
| 93 | + - The fromAddress in the status will show purchasing address |
| 94 | + - The purchaseData will contain more information you previously for the purchase details |
| 95 | + - Validate the information. For example, 100 USDC was sent to your wallet. |
| 96 | + 5. Send a contract call to Engine for the float wallet to purchase the item |
| 97 | + - For example, send a transaction to the float wallet for `mintTo(fromAddress)` |
| 98 | + - 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 |
| 99 | + 6. Confirm the purchase was successful. |
| 100 | + </Step> |
| 101 | +</Steps> |
| 102 | + |
| 103 | +Once you've completed all of these steps, you'll be ready to offer a great purchase UX for your users. |
0 commit comments