Skip to content

Commit 644519d

Browse files
authored
Merge pull request #3 from thirdweb-dev/yash/use-checkout-widget
use checkout widget
2 parents 4cda909 + 29ae4f3 commit 644519d

9 files changed

Lines changed: 304 additions & 6547 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Dependencies
22
node_modules/
33
vendor/
4+
.pnpm-store/
45

56
# Build output
67
build/

includes/class-thirdweb-blocks-support.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,11 @@ public function get_payment_method_data() {
8484
'description' => $this->get_setting('description'),
8585
'supports' => $this->get_supported_features(),
8686

87-
// thirdweb configuration
88-
'clientId' => $this->get_setting('client_id'),
87+
// thirdweb configuration (no Client ID needed for iframe widget)
8988
'seller' => $this->get_setting('seller_wallet'),
9089
'chainId' => (int) $this->get_setting('chain_id'),
9190
'tokenAddress' => $this->get_setting('token_address'),
92-
'theme' => $this->get_setting('theme') ?: 'light',
91+
'theme' => $this->get_setting('theme', 'dark'),
9392

9493
// Icons/branding
9594
'icon' => THIRDWEB_WC_PLUGIN_URL . 'assets/icon.svg',

includes/class-thirdweb-payment-gateway.php

Lines changed: 64 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,11 @@ public function __construct() {
3232
$this->description = $this->get_option('description');
3333
$this->enabled = $this->get_option('enabled');
3434

35-
// thirdweb specific settings
36-
// Use .env value as default if WooCommerce setting is empty
37-
$env_client_id = thirdweb_wc_get_env('THIRDWEB_CLIENT_ID', '');
38-
$this->client_id = $this->get_option('client_id') ?: $env_client_id;
35+
// thirdweb specific settings (no Client ID needed for iframe widget)
3936
$this->seller_wallet = $this->get_option('seller_wallet');
4037
$this->chain_id = $this->get_option('chain_id');
4138
$this->token_address = $this->get_option('token_address');
42-
$this->theme = $this->get_option('theme');
39+
$this->theme = $this->get_option('theme', 'dark');
4340

4441
// Save settings hook
4542
add_action('woocommerce_update_options_payment_gateways_' . $this->id, [$this, 'process_admin_options']);
@@ -69,23 +66,10 @@ public function init_form_fields() {
6966
'description' => __('Payment method description shown at checkout', 'thirdweb-wc'),
7067
'default' => __('Pay securely with USDC, USDT or other stablecoins from any wallet.', 'thirdweb-wc'),
7168
],
72-
'client_id' => [
73-
'title' => __('thirdweb Client ID', 'thirdweb-wc'),
74-
'type' => 'text',
75-
'description' => sprintf(
76-
__('Get your Client ID from <a href="%s" target="_blank">thirdweb Dashboard</a>. Create a new project if you haven\'t already. Can also be set via .env file for development.', 'thirdweb-wc'),
77-
'https://thirdweb.com/dashboard'
78-
),
79-
'default' => thirdweb_wc_get_env('THIRDWEB_CLIENT_ID', ''),
80-
'placeholder' => __('e.g., abc123def456...', 'thirdweb-wc'),
81-
],
8269
'seller_wallet' => [
8370
'title' => __('Seller Wallet Address', 'thirdweb-wc'),
8471
'type' => 'text',
85-
'description' => sprintf(
86-
__('Your project wallet address that will receive all payments. Get this from your <a href="%s" target="_blank">thirdweb project dashboard</a>.', 'thirdweb-wc'),
87-
'https://thirdweb.com/dashboard'
88-
),
72+
'description' => __('Your wallet address that will receive all payments. Use any Ethereum-compatible wallet (MetaMask, Coinbase Wallet, etc.).', 'thirdweb-wc'),
8973
'default' => '',
9074
'placeholder' => __('0x...', 'thirdweb-wc'),
9175
'custom_attributes' => [
@@ -108,20 +92,20 @@ public function init_form_fields() {
10892
'token_address' => [
10993
'title' => __('Token Address (Optional)', 'thirdweb-wc'),
11094
'type' => 'text',
111-
'description' => __('USDC/USDT contract address for the chain above. Make sure the token address matches your selected chain. Leave empty to accept the native token (ETH, MATIC, etc.). Default is USDC on Base (chain 8453).', 'thirdweb-wc'),
95+
'description' => __('USDC/USDT contract address for the chain above. Make sure the token address matches your selected chain. Leave empty to accept any stablecoin. Default is USDC on Base (chain 8453).', 'thirdweb-wc'),
11296
'default' => '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', // USDC on Base
11397
'placeholder' => __('0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', 'thirdweb-wc'),
11498
],
11599
'theme' => [
116100
'title' => __('Widget Theme', 'thirdweb-wc'),
117101
'type' => 'select',
118-
'description' => __('Choose the color theme for the checkout widget. Light theme is recommended for most sites.', 'thirdweb-wc'),
119-
'default' => 'light',
120-
'desc_tip' => true,
102+
'description' => __('Choose the theme for the checkout widget. Default is dark.', 'thirdweb-wc'),
103+
'default' => 'dark',
121104
'options' => [
122-
'light' => __('Light', 'thirdweb-wc'),
123105
'dark' => __('Dark', 'thirdweb-wc'),
106+
'light' => __('Light', 'thirdweb-wc'),
124107
],
108+
'desc_tip' => true,
125109
],
126110
];
127111
}
@@ -134,28 +118,39 @@ public function payment_fields() {
134118
echo wpautop(wptexturize($this->description));
135119
}
136120

137-
// Container for React to mount the CheckoutWidget
138-
echo '<div id="thirdweb-checkout-widget"
139-
data-client-id="' . esc_attr($this->client_id) . '"
140-
data-seller="' . esc_attr($this->seller_wallet) . '"
141-
data-chain-id="' . esc_attr($this->chain_id) . '"
142-
data-token-address="' . esc_attr($this->token_address) . '"
143-
data-amount="' . esc_attr(WC()->cart->get_total('edit')) . '"
144-
data-currency="' . esc_attr(get_woocommerce_currency()) . '">
145-
</div>';
121+
// Container for iframe checkout widget (legacy checkout)
122+
$amount = WC()->cart->get_total('edit');
123+
$params = [
124+
'chain' => $this->chain_id,
125+
'amount' => $amount,
126+
'seller' => $this->seller_wallet,
127+
];
128+
129+
// Only add tokenAddress if provided
130+
if (!empty($this->token_address)) {
131+
$params['tokenAddress'] = $this->token_address;
132+
}
133+
134+
// Add theme (default is dark, but allow override)
135+
$params['theme'] = $this->theme;
146136

147-
// Hidden field to store transaction hash
148-
echo '<input type="hidden" name="thirdweb_tx_hash" id="thirdweb_tx_hash" value="" />';
137+
$iframe_url = 'https://thirdweb.com/bridge/checkout-widget?' . http_build_query($params);
138+
139+
echo '<div id="thirdweb-checkout-widget">';
140+
echo '<iframe src="' . esc_url($iframe_url) . '" height="700px" width="100%" style="border: 0;" title="thirdweb Checkout Widget"></iframe>';
141+
echo '</div>';
149142
}
150143

151144
/**
152145
* Validate payment fields
146+
*
147+
* Note: For WooCommerce Blocks, validation happens in the React component.
148+
* This method is mainly for legacy checkout.
153149
*/
154150
public function validate_fields() {
155-
if (empty($_POST['thirdweb_tx_hash'])) {
156-
wc_add_notice(__('Please complete the payment.', 'thirdweb-wc'), 'error');
157-
return false;
158-
}
151+
// Always return true - validation is handled by:
152+
// 1. React component for Blocks (checks paymentComplete before allowing submission)
153+
// 2. Frontend JavaScript for legacy checkout
159154
return true;
160155
}
161156

@@ -164,82 +159,52 @@ public function validate_fields() {
164159
*/
165160
public function process_payment($order_id) {
166161
$order = wc_get_order($order_id);
167-
$tx_hash = sanitize_text_field($_POST['thirdweb_tx_hash'] ?? '');
168-
169-
if (empty($tx_hash)) {
170-
// Payment not yet completed - wait for webhook
171-
$order->update_status('pending', __('Awaiting stablecoin payment confirmation.', 'thirdweb-wc'));
172-
173-
return [
174-
'result' => 'success',
175-
'redirect' => $this->get_return_url($order),
176-
];
177-
}
178-
179-
// Transaction hash provided - verify on-chain
180-
if ($this->verify_transaction($tx_hash, $order)) {
181-
$order->payment_complete($tx_hash);
182-
$order->add_order_note(
183-
sprintf(__('Stablecoin payment completed. Transaction: %s', 'thirdweb-wc'), $tx_hash)
184-
);
185-
186-
WC()->cart->empty_cart();
187-
188-
return [
189-
'result' => 'success',
190-
'redirect' => $this->get_return_url($order),
191-
];
192-
}
193-
194-
wc_add_notice(__('Payment verification failed. Please try again.', 'thirdweb-wc'), 'error');
195-
return ['result' => 'failure'];
196-
}
197-
198-
/**
199-
* Verify transaction on-chain
200-
*/
201-
private function verify_transaction($tx_hash, $order) {
202-
// Use thirdweb RPC to verify the transaction
203-
$rpc_url = 'https://' . $this->chain_id . '.rpc.thirdweb.com/' . $this->client_id;
204162

205-
$response = wp_remote_post($rpc_url, [
206-
'headers' => ['Content-Type' => 'application/json'],
207-
'body' => json_encode([
208-
'jsonrpc' => '2.0',
209-
'method' => 'eth_getTransactionReceipt',
210-
'params' => [$tx_hash],
211-
'id' => 1,
212-
]),
213-
]);
214-
215-
if (is_wp_error($response)) {
216-
return false;
163+
// Get chain ID from payment data (WooCommerce Blocks sends it in payment_data array)
164+
$chain_id = $this->chain_id;
165+
166+
if (isset($_POST['payment_data']) && is_array($_POST['payment_data'])) {
167+
foreach ($_POST['payment_data'] as $data) {
168+
if (isset($data['key']) && $data['key'] === 'thirdweb_chain_id') {
169+
$chain_id = sanitize_text_field($data['value'] ?? $this->chain_id);
170+
break;
171+
}
172+
}
217173
}
218-
219-
$body = json_decode(wp_remote_retrieve_body($response), true);
220-
$receipt = $body['result'] ?? null;
221-
222-
if (!$receipt || $receipt['status'] !== '0x1') {
223-
return false;
174+
175+
// Fallback to legacy format
176+
if ($chain_id === $this->chain_id && isset($_POST['thirdweb_chain_id'])) {
177+
$chain_id = sanitize_text_field($_POST['thirdweb_chain_id']);
224178
}
225179

226-
// Additional verification: check recipient and amount in logs
227-
// This is simplified - production code should decode transfer events
228-
return true;
180+
// Payment was completed via checkout widget - trust thirdweb's confirmation
181+
$order->payment_complete();
182+
$order->add_order_note(
183+
sprintf(
184+
__('Stablecoin payment completed via thirdweb checkout widget. Chain: %s', 'thirdweb-wc'),
185+
$chain_id
186+
)
187+
);
188+
189+
WC()->cart->empty_cart();
190+
191+
return [
192+
'result' => 'success',
193+
'redirect' => $this->get_return_url($order),
194+
];
229195
}
230196

231197
/**
232198
* Get config for frontend
233199
*/
234200
public function get_frontend_config() {
235201
return [
236-
'clientId' => $this->client_id,
237202
'seller' => $this->seller_wallet,
238203
'chainId' => (int) $this->chain_id,
239204
'tokenAddress' => $this->token_address,
205+
'theme' => $this->theme,
240206
'title' => $this->title,
241207
'description' => $this->description,
242-
'theme' => $this->theme ?: 'light',
243208
];
244209
}
245210
}

package.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,7 @@
2020
"@wordpress/scripts": "^31.1.0",
2121
"typescript": "^5.9.3"
2222
},
23-
"dependencies": {
24-
"thirdweb": "^5.116.1"
25-
},
23+
"dependencies": {},
2624
"peerDependencies": {
2725
"react": "^18.0.0",
2826
"react-dom": "^18.0.0"

0 commit comments

Comments
 (0)