Changeset 3472118
- Timestamp:
- 03/01/2026 03:03:40 PM (5 weeks ago)
- Location:
- coinsnap-bitcoin-invoice-form
- Files:
-
- 52 added
- 9 edited
-
assets/screenshot-2.png (modified) (previous)
-
assets/screenshot-3.png (modified) (previous)
-
tags/1.1.0 (added)
-
tags/1.1.0/assets (added)
-
tags/1.1.0/assets/css (added)
-
tags/1.1.0/assets/css/admin.css (added)
-
tags/1.1.0/assets/css/frontend.css (added)
-
tags/1.1.0/assets/css/index.php (added)
-
tags/1.1.0/assets/index.php (added)
-
tags/1.1.0/assets/js (added)
-
tags/1.1.0/assets/js/admin.js (added)
-
tags/1.1.0/assets/js/frontend.js (added)
-
tags/1.1.0/assets/js/index.php (added)
-
tags/1.1.0/coinsnap-bitcoin-invoice-form.php (added)
-
tags/1.1.0/index.php (added)
-
tags/1.1.0/languages (added)
-
tags/1.1.0/languages/index.php (added)
-
tags/1.1.0/readme.txt (added)
-
tags/1.1.0/src (added)
-
tags/1.1.0/src/Admin (added)
-
tags/1.1.0/src/Admin/class-coinsnapbif-admin-logs-page.php (added)
-
tags/1.1.0/src/Admin/class-coinsnapbif-admin-settings.php (added)
-
tags/1.1.0/src/Admin/class-coinsnapbif-admin-transactions-page.php (added)
-
tags/1.1.0/src/Admin/index.php (added)
-
tags/1.1.0/src/CPT (added)
-
tags/1.1.0/src/CPT/class-coinsnapbif-cpt-invoice-form-post-type.php (added)
-
tags/1.1.0/src/CPT/index.php (added)
-
tags/1.1.0/src/Database (added)
-
tags/1.1.0/src/Database/class-installer.php (added)
-
tags/1.1.0/src/Database/index.php (added)
-
tags/1.1.0/src/Providers (added)
-
tags/1.1.0/src/Providers/Payment (added)
-
tags/1.1.0/src/Providers/Payment/class-btcpayprovider.php (added)
-
tags/1.1.0/src/Providers/Payment/class-coinsnapprovider.php (added)
-
tags/1.1.0/src/Providers/Payment/class-paymentproviderinterface.php (added)
-
tags/1.1.0/src/Providers/Payment/index.php (added)
-
tags/1.1.0/src/Providers/index.php (added)
-
tags/1.1.0/src/Rest (added)
-
tags/1.1.0/src/Rest/class-coinsnapbif-rest-routes.php (added)
-
tags/1.1.0/src/Rest/index.php (added)
-
tags/1.1.0/src/Services (added)
-
tags/1.1.0/src/Services/class-coinsnapbif-services-payment-service.php (added)
-
tags/1.1.0/src/Services/index.php (added)
-
tags/1.1.0/src/Shortcode (added)
-
tags/1.1.0/src/Shortcode/class-coinsnapbif-shortcode-invoice-form-shortcode.php (added)
-
tags/1.1.0/src/Shortcode/index.php (added)
-
tags/1.1.0/src/Util (added)
-
tags/1.1.0/src/Util/class-coinsnapbif-log-levels.php (added)
-
tags/1.1.0/src/Util/class-coinsnapbif-logger.php (added)
-
tags/1.1.0/src/Util/class-coinsnapbif-util-provider-factory.php (added)
-
tags/1.1.0/src/Util/index.php (added)
-
tags/1.1.0/src/class-coinsnapbif-constants.php (added)
-
tags/1.1.0/src/class-coinsnapbif-plugin.php (added)
-
tags/1.1.0/src/index.php (added)
-
trunk/assets/js/admin.js (modified) (1 diff)
-
trunk/coinsnap-bitcoin-invoice-form.php (modified) (2 diffs)
-
trunk/readme.txt (modified) (2 diffs)
-
trunk/src/Admin/class-coinsnapbif-admin-settings.php (modified) (3 diffs)
-
trunk/src/Providers/Payment/class-btcpayprovider.php (modified) (1 diff)
-
trunk/src/class-coinsnapbif-constants.php (modified) (1 diff)
-
trunk/src/class-coinsnapbif-plugin.php (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
coinsnap-bitcoin-invoice-form/trunk/assets/js/admin.js
r3459088 r3472118 52 52 53 53 54 $('#coinsnapbif_btcpay_wizard_button').click(function(e) {54 $('#coinsnapbif_btcpay_wizard_button').click(function(e) { 55 55 e.preventDefault(); 56 const host = $('# btcpay_url').val();56 const host = $('#coinsnapbif_btcpay_url').val(); 57 57 if (isCoinsnapBIFValidUrl(host)) { 58 58 let data = { -
coinsnap-bitcoin-invoice-form/trunk/coinsnap-bitcoin-invoice-form.php
r3459146 r3472118 4 4 * Plugin URI: https://coinsnap.io/modules/bitcoin-invoice/ 5 5 * Description: Generate and embed customizable Bitcoin Invoice Forms on your website. Customers can complete and pay invoices directly on your site with payment processing via Coinsnap or BTCPay Server. 6 * Version: 1. 0.3.26 * Version: 1.1.0 7 7 * Author: Coinsnap 8 8 * Author URI: https://coinsnap.io/ … … 25 25 26 26 if(!defined('COINSNAPBIF_REFERRAL_CODE' ) ) { define( 'COINSNAPBIF_REFERRAL_CODE', 'D85536' );} 27 if(!defined('COINSNAPBIF_VERSION' ) ) { define( 'COINSNAPBIF_VERSION', '1. 0.3.2' );}27 if(!defined('COINSNAPBIF_VERSION' ) ) { define( 'COINSNAPBIF_VERSION', '1.1.0' );} 28 28 if(!defined('COINSNAPBIF_PHP_VERSION' ) ) { define( 'COINSNAPBIF_PHP_VERSION', '7.4' );} 29 29 if(!defined('COINSNAP_CURRENCIES')){define( 'COINSNAP_CURRENCIES', array("EUR","USD","SATS","BTC","CAD","JPY","GBP","CHF","RUB") );} -
coinsnap-bitcoin-invoice-form/trunk/readme.txt
r3459146 r3472118 4 4 Tags: Lightning, bitcoin, invoice form, BTCPay 5 5 Tested up to: 6.9 6 Stable tag: 1. 0.3.26 Stable tag: 1.1.0 7 7 License: GPL2 8 8 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 250 250 = 1.0.3.2 :: 2026-02-11 = 251 251 * Updated Coinsnap and BTCPay server errors handler 252 253 = 1.1.0 :: 2026-03-01 = 254 * Update: added BTCPay server connection wizard on Settings page 255 * Update: deleted setting Disable Webhook Verification -
coinsnap-bitcoin-invoice-form/trunk/src/Admin/class-coinsnapbif-admin-settings.php
r3458758 r3472118 145 145 function () { 146 146 $s = self::get_settings(); 147 echo '<input type="url" class="regular-text" name="' . esc_attr( self::OPTION_KEY ) . '[btcpay_host]" value="' . esc_attr( $s['btcpay_host'] ) . '" />';147 echo '<input type="url" id="coinsnapbif_btcpay_url" class="regular-text" name="' . esc_attr( self::OPTION_KEY ) . '[btcpay_host]" value="' . esc_attr( $s['btcpay_host'] ) . '" /><br/><button class="button btcpay-apikey-link" type="button" id="coinsnapbif_btcpay_wizard_button" target="_blank">'. esc_html__('Generate API key','coinsnap-bitcoin-invoice-form') .'</button>'; 148 148 }, 149 149 'coinsnapbif-settings', … … 202 202 'coinsnapbif-settings', 203 203 'coinsnapbif_advanced' 204 ); 204 );/* 205 205 add_settings_field( 206 206 'disable_webhook_verification', … … 212 212 'coinsnapbif-settings', 213 213 'coinsnapbif_advanced' 214 ); 214 );*/ 215 215 } 216 216 -
coinsnap-bitcoin-invoice-form/trunk/src/Providers/Payment/class-btcpayprovider.php
r3459146 r3472118 65 65 return array('error' => true,'message'=>__('BTCPay server request error','coinsnap-bitcoin-invoice-form'),'code' => $code, 'result' => $result); 66 66 } 67 } 68 67 } 69 68 70 69 /** -
coinsnap-bitcoin-invoice-form/trunk/src/class-coinsnapbif-constants.php
r3458758 r3472118 33 33 34 34 /** BTCPay endpoint (relative to host). */ 35 public const BTCPAY_STORE_ENDPOINT = '/api/v1/stores/%s'; 35 public const BTCPAY_STORES_ENDPOINT = '/api/v1/stores'; 36 public const BTCPAY_STORE_ENDPOINT = '/api/v1/stores/%s'; 36 37 public const BTCPAY_INVOICES_ENDPOINT = '/api/v1/stores/%s/invoices'; 37 38 public const BTCPAY_WEBHOOKS_ENDPOINT = '/api/v1/stores/%s/webhooks'; -
coinsnap-bitcoin-invoice-form/trunk/src/class-coinsnapbif-plugin.php
r3460775 r3472118 169 169 170 170 public function btcpayApiUrlHandler(){ 171 171 $_nonce = filter_input(INPUT_POST,'apiNonce',FILTER_SANITIZE_STRING); 172 if ( !wp_verify_nonce( $_nonce, 'coinsnap-ajax-nonce' ) ) { 173 wp_die('Unauthorized!', '', ['response' => 401]); 174 } 175 176 if ( current_user_can( 'manage_options' ) ) { 177 $host = filter_var(filter_input(INPUT_POST,'host',FILTER_SANITIZE_STRING), FILTER_VALIDATE_URL); 178 179 if ($host === false || (substr( $host, 0, 7 ) !== "http://" && substr( $host, 0, 8 ) !== "https://")) { 180 wp_send_json_error("Error validating BTCPayServer URL."); 181 } 182 183 $permissions = array_merge([ 184 'btcpay.store.canviewinvoices', 185 'btcpay.store.cancreateinvoice', 186 'btcpay.store.canviewstoresettings', 187 'btcpay.store.canmodifyinvoices' 188 ], 189 [ 190 'btcpay.store.cancreatenonapprovedpullpayments', 191 'btcpay.store.webhooks.canmodifywebhooks', 192 ]); 193 194 try { 195 // Create the redirect url to BTCPay instance. 196 $url = $this->getAuthorizeUrl( 197 $host, 198 $permissions, 199 'CoinsnapBIF', 200 true, 201 true, 202 home_url('?coinsnapBIF-settings-callback'), 203 null 204 ); 205 206 // Store the host to options before we leave the site. 207 coinsnap_settings_update(AdminSettings::OPTION_KEY,['btcpay_host' => $host]); 208 209 // Return the redirect url. 210 wp_send_json_success(['url' => $url]); 211 } 212 213 catch (\Throwable $e) { 214 215 } 216 } 217 wp_send_json_error("Error processing Ajax request."); 218 } 219 220 public function getAuthorizeUrl(string $baseUrl, array $permissions, ?string $applicationName, ?bool $strict, ?bool $selectiveStores, ?string $redirectToUrlAfterCreation, ?string $applicationIdentifier): string { 221 $url = rtrim($baseUrl, '/') . '/api-keys/authorize'; 222 223 $params = []; 224 $params['permissions'] = $permissions; 225 $params['applicationName'] = $applicationName; 226 $params['strict'] = $strict; 227 $params['selectiveStores'] = $selectiveStores; 228 $params['redirect'] = $redirectToUrlAfterCreation; 229 $params['applicationIdentifier'] = $applicationIdentifier; 230 231 // Take out NULL values 232 $params = array_filter($params, function ($value) { 233 return $value !== null; 234 }); 235 236 $queryParams = []; 237 238 foreach ($params as $param => $value) { 239 if ($value === true) { 240 $value = 'true'; 241 } 242 if ($value === false) { 243 $value = 'false'; 244 } 245 246 if (is_array($value)) { 247 foreach ($value as $item) { 248 if ($item === true) { 249 $item = 'true'; 250 } 251 if ($item === false) { 252 $item = 'false'; 253 } 254 $queryParams[] = $param . '=' . urlencode((string)$item); 255 } 256 } else { 257 $queryParams[] = $param . '=' . urlencode((string)$value); 258 } 259 } 260 261 $url .= '?' . implode("&", $queryParams); 262 return $url; 172 263 } 173 264 … … 503 594 } 504 595 } 596 597 add_action('init', function() { 598 // Setting up and handling custom endpoint for api key redirect from BTCPay Server. 599 add_rewrite_endpoint('coinsnapBIF-settings-callback', EP_ROOT); 600 }); 601 602 // To be able to use the endpoint without appended url segments we need to do this. 603 add_filter('request', function($vars){ 604 if (isset($vars['coinsnapBIF-settings-callback'])) { 605 $vars['coinsnapBIF-settings-callback'] = true; 606 $vars['coinsnapBIF-nonce'] = wp_create_nonce('coinsnap-bitcoin-invoice-form-btcpay-nonce'); 607 } 608 return $vars; 609 }); 610 611 if(!function_exists('coinsnap_settings_update')){ 612 function coinsnap_settings_update($option,$data){ 613 614 $form_data = get_option($option, []); 615 616 foreach($data as $key => $value){ 617 $form_data[$key] = $value; 618 } 619 620 update_option($option,$form_data); 621 } 622 } 623 624 // Adding template redirect handling for coinsnapBIF-settings-callback. 625 add_action( 'template_redirect', function(){ 626 627 global $wp_query; 628 629 // Only continue on a coinsnapBIF-settings-callback request. 630 if (!isset( $wp_query->query_vars['coinsnapBIF-settings-callback'])) { 631 return; 632 } 633 634 if(!isset($wp_query->query_vars['coinsnapBIF-nonce']) || !wp_verify_nonce($wp_query->query_vars['coinsnapBIF-nonce'],'coinsnap-bitcoin-invoice-form-btcpay-nonce')){ 635 return; 636 } 637 638 $CoinsnapBTCPaySettingsUrl = admin_url('/admin.php?page=coinsnapbif-settings'); 639 640 $rawData = file_get_contents('php://input'); 641 $form_data = get_option(AdminSettings::OPTION_KEY, []); 642 643 $btcpay_server_url = $form_data['btcpay_host']; 644 $btcpay_api_key = filter_input(INPUT_POST,'apiKey',FILTER_SANITIZE_FULL_SPECIAL_CHARS); 645 646 $request_url = $btcpay_server_url.'/api/v1/stores'; 647 $args = array( 648 'method' => 'GET', 649 'headers' => array( 650 'Authorization' => 'token ' . $btcpay_api_key, 651 'Content-Type' => 'application/json', 652 ), 653 'timeout' => 20 654 ); 655 656 $res = wp_remote_request( $request_url, $args ); 657 $code = wp_remote_retrieve_response_code( $res ); 658 $getstores = json_decode( wp_remote_retrieve_body( $res ), true ); 659 660 if($code >= 200 && $code < 300 && is_array($getstores)){ 661 if (count($getstores) < 1) { 662 //$messageAbort = __('Error on verifiying redirected API Key with stored BTCPay Server url. Aborting API wizard. Please try again or continue with manual setup.', 'coinsnap-bitcoin-invoice-form'); 663 wp_redirect($CoinsnapBTCPaySettingsUrl); 664 } 665 } 666 667 // Data does get submitted with url-encoded payload, so parse $_POST here. 668 if (!empty($_POST)) { 669 $data['apiKey'] = filter_input(INPUT_POST,'apiKey',FILTER_SANITIZE_FULL_SPECIAL_CHARS) ?? null; 670 if(isset($_POST['permissions'])){ 671 $permissions = array_map('sanitize_text_field', wp_unslash($_POST['permissions'])); 672 if(is_array($permissions)){ 673 foreach ($permissions as $key => $value) { 674 $data['permissions'][$key] = sanitize_text_field($permissions[$key] ?? null); 675 } 676 } 677 } 678 } 679 680 if (isset($data['apiKey']) && isset($data['permissions'])) { 681 682 $REQUIRED_PERMISSIONS = [ 683 'btcpay.store.canviewinvoices', 684 'btcpay.store.cancreateinvoice', 685 'btcpay.store.canviewstoresettings', 686 'btcpay.store.canmodifyinvoices' 687 ]; 688 $OPTIONAL_PERMISSIONS = [ 689 'btcpay.store.cancreatenonapprovedpullpayments', 690 'btcpay.store.webhooks.canmodifywebhooks', 691 ]; 692 693 $btcpay_server_permissions = $data['permissions']; 694 695 $permissions = array_reduce($btcpay_server_permissions, static function (array $carry, string $permission) { 696 return array_merge($carry, [explode(':', $permission)[0]]); 697 }, []); 698 699 // Remove optional permissions so that only required ones are left. 700 $permissions = array_diff($permissions, $OPTIONAL_PERMISSIONS); 701 702 $hasRequiredPermissions = (empty(array_merge(array_diff($REQUIRED_PERMISSIONS, $permissions), array_diff($permissions, $REQUIRED_PERMISSIONS))))? true : false; 703 704 $hasSingleStore = true; 705 $storeId = null; 706 foreach ($btcpay_server_permissions as $perms) { 707 if (2 !== count($exploded = explode(':', $perms))) { return false; } 708 if (null === ($receivedStoreId = $exploded[1])) { $hasSingleStore = false; } 709 if ($storeId === $receivedStoreId) { continue; } 710 if (null === $storeId) { $storeId = $receivedStoreId; continue; } 711 $hasSingleStore = false; 712 } 713 714 if ($hasSingleStore && $hasRequiredPermissions) { 715 716 coinsnap_settings_update( 717 AdminSettings::OPTION_KEY,[ 718 'btcpay_api_key' => $data['apiKey'], 719 'btcpay_store_id' => explode(':', $btcpay_server_permissions[0])[1], 720 'payment_provider' => 'btcpay' 721 ]); 722 723 wp_redirect($CoinsnapBTCPaySettingsUrl); 724 exit(); 725 } 726 else { 727 wp_redirect($CoinsnapBTCPaySettingsUrl); 728 exit(); 729 } 730 } 731 732 wp_redirect($CoinsnapBTCPaySettingsUrl); 733 exit(); 734 });
Note: See TracChangeset
for help on using the changeset viewer.