├── .dockerignore ├── src ├── assets │ ├── css │ │ ├── pairing.css │ │ └── token.css │ ├── img │ │ ├── icon.png │ │ ├── logo.png │ │ └── ajax-loader.gif │ ├── screenshot-1.png │ ├── screenshot-2.png │ ├── screenshot-3.png │ ├── screenshot-4.png │ ├── screenshot-5.png │ └── js │ │ └── pairing.js ├── class-wc-gateway-bitpay.php ├── templates │ ├── paymentStatus.tpl │ ├── token.tpl │ └── pairing.tpl ├── uninstall.php ├── languages │ └── btcpay-for-woocommerce.pot ├── readme.txt └── class-wc-gateway-btcpay.php ├── .travis.yml ├── docs └── img │ ├── admin.png │ ├── token.png │ ├── pairingcode.png │ └── ordersettings.png ├── woocommerce ├── docker-bitcoin-cli.ps1 ├── docker-litecoin-cli.ps1 ├── README.md ├── Dockerfile └── docker-compose.yml ├── tests └── EmptyTest.php ├── docker-build.ps1 ├── phpunit.xml ├── .gitignore ├── .github └── ISSUE_TEMPLATE │ ├── ---feature-request.md │ └── ----bug-report-.md ├── woocommerce-plugin.code-workspace ├── package.json ├── composer.json ├── LICENSE ├── Dockerfile ├── wp-repo-publish.ps1 ├── Gruntfile.js ├── GUIDE.md ├── README.md └── CHANGELOG.md /.dockerignore: -------------------------------------------------------------------------------- 1 | docker-build.ps1 2 | dist/ 3 | woocommerce/ 4 | Dockerfile -------------------------------------------------------------------------------- /src/assets/css/pairing.css: -------------------------------------------------------------------------------- 1 | .btcpay-pairing--hidden { 2 | display: none; 3 | } -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | php: 3 | - 5.4 4 | - 5.5 5 | - 5.6 6 | - hhvm -------------------------------------------------------------------------------- /docs/img/admin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/btcpayserver/woocommerce-plugin/HEAD/docs/img/admin.png -------------------------------------------------------------------------------- /docs/img/token.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/btcpayserver/woocommerce-plugin/HEAD/docs/img/token.png -------------------------------------------------------------------------------- /src/class-wc-gateway-bitpay.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/img/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/btcpayserver/woocommerce-plugin/HEAD/src/assets/img/icon.png -------------------------------------------------------------------------------- /src/assets/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/btcpayserver/woocommerce-plugin/HEAD/src/assets/img/logo.png -------------------------------------------------------------------------------- /docs/img/pairingcode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/btcpayserver/woocommerce-plugin/HEAD/docs/img/pairingcode.png -------------------------------------------------------------------------------- /docs/img/ordersettings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/btcpayserver/woocommerce-plugin/HEAD/docs/img/ordersettings.png -------------------------------------------------------------------------------- /src/assets/screenshot-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/btcpayserver/woocommerce-plugin/HEAD/src/assets/screenshot-1.png -------------------------------------------------------------------------------- /src/assets/screenshot-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/btcpayserver/woocommerce-plugin/HEAD/src/assets/screenshot-2.png -------------------------------------------------------------------------------- /src/assets/screenshot-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/btcpayserver/woocommerce-plugin/HEAD/src/assets/screenshot-3.png -------------------------------------------------------------------------------- /src/assets/screenshot-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/btcpayserver/woocommerce-plugin/HEAD/src/assets/screenshot-4.png -------------------------------------------------------------------------------- /src/assets/screenshot-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/btcpayserver/woocommerce-plugin/HEAD/src/assets/screenshot-5.png -------------------------------------------------------------------------------- /src/assets/img/ajax-loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/btcpayserver/woocommerce-plugin/HEAD/src/assets/img/ajax-loader.gif -------------------------------------------------------------------------------- /woocommerce/docker-bitcoin-cli.ps1: -------------------------------------------------------------------------------- 1 | docker exec -ti woocommerce_bitcoind_1 bitcoin-cli -regtest -conf="/data/bitcoin.conf" -datadir="/data" $args -------------------------------------------------------------------------------- /woocommerce/docker-litecoin-cli.ps1: -------------------------------------------------------------------------------- 1 | docker exec -ti woocommerce_litecoind litecoin-cli -regtest -conf="/data/litecoin.conf" -datadir="/data" $args 2 | -------------------------------------------------------------------------------- /tests/EmptyTest.php: -------------------------------------------------------------------------------- 1 | assertEquals(true, true); 7 | } 8 | } -------------------------------------------------------------------------------- /src/templates/paymentStatus.tpl: -------------------------------------------------------------------------------- 1 |
2 |

3 | {$statusTitle} 4 |

5 |

6 | 7 | {$paymentStatus} 8 | 9 |

10 |
-------------------------------------------------------------------------------- /docker-build.ps1: -------------------------------------------------------------------------------- 1 | rm dist -Force -Recurse 2 | mkdir "dist" 3 | docker build -t woocommerce_bitpay . 4 | docker run -ti -v "$pwd/dist:/app/dist" --rm woocommerce_bitpay 5 | echo "Output available in $pwd\dist\btcpay-for-woocommerce.zip" 6 | Copy-Item "$pwd\dist\btcpay-for-woocommerce\*" "$pwd\woocommerce\html\wp-content\plugins\btcpay-for-woocommerce" -Force -Recurse -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | ./tests/ 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/uninstall.php: -------------------------------------------------------------------------------- 1 | query("DELETE FROM $wpdb->options WHERE option_name LIKE 'woocommerce_btcpay%';"); 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /bin/** 2 | /build/cache/ 3 | /build/docs/ 4 | /build/dist/ 5 | /build/logs/ 6 | /docs/_build/ 7 | /vendor/ 8 | /.settings/ 9 | .project 10 | .buildpath 11 | composer.lock 12 | composer.phar 13 | /dist/ 14 | /node_modules/ 15 | npm_debug.log 16 | /wordpress/ 17 | wp-cli.yml 18 | wp-tests-config.php 19 | woocommerce/html 20 | \.idea/\.idea\.woocommerce-plugin/\.idea/ 21 | 22 | \.idea/\.idea\.woocommerce-plugin/ 23 | 24 | dist2/ 25 | -------------------------------------------------------------------------------- /woocommerce/README.md: -------------------------------------------------------------------------------- 1 | # Test framework 2 | 3 | You can run the whole infrastructure (BTCPay + Woocommerce) via `docker-compose up`. 4 | This will expose btcpay on `http://localhost:8081/` and woocommerce on `http://localhost:8080/`. 5 | 6 | You can use Selenium IDE plugin for chrome and run `selenium-woocommerce-btcpay-test.side`. 7 | 8 | This selenium project is meant to recreate a store easily, to test btcpayserver. 9 | It is not very reliable yet, so it may need some fixing. -------------------------------------------------------------------------------- /src/templates/token.tpl: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 | 5 |
6 |
Label:%s
7 |
ID:%s
8 |
9 | -------------------------------------------------------------------------------- /src/templates/pairing.tpl: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | 5 | 6 |
Get a pairing code: 7 | 8 |
9 |
-------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/---feature-request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "\U0001F680 Feature request" 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /woocommerce-plugin.code-workspace: -------------------------------------------------------------------------------- 1 | { 2 | "folders": [ 3 | { 4 | "path": "." 5 | } 6 | ], 7 | "settings": 8 | { 9 | "files.exclude": { 10 | "**/.git": true, // this is a default value 11 | "**/dist": true, // this is a default value 12 | "**/woocommerce/html": true, // this is a default value 13 | "**/.DS_Store": true, // this is a default value 14 | 15 | "**/node_modules": true, // this excludes all folders 16 | // named "node_modules" from 17 | // the explore tree 18 | 19 | // alternative version 20 | "node_modules": true // this excludes the folder 21 | // only from the root of 22 | // your workspace 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": "BTCPay", 3 | "name": "woocommerce-plugin", 4 | "license": "MIT", 5 | "description": "BTCPay payment gateway for WooCommerce", 6 | "version": "2.2.24", 7 | "repository": { 8 | "type": "git", 9 | "url": "git://github.com/btcpayserver/woocommerce-plugin.git" 10 | }, 11 | "dependencies": {}, 12 | "devDependencies": { 13 | "grunt": "^1.0.1", 14 | "grunt-cli": "^1.2.0", 15 | "grunt-contrib-clean": "^1.0.0", 16 | "grunt-contrib-compress": "^1.3.0", 17 | "grunt-contrib-copy": "^1.0.0", 18 | "grunt-contrib-cssmin": "^1.0.1", 19 | "grunt-contrib-watch": "^1.0.0", 20 | "grunt-php-cs-fixer": "0.0.8" 21 | }, 22 | "optionalDependencies": {}, 23 | "engines": { 24 | "node": "*" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "repositories": [ 3 | { 4 | "type": "git", 5 | "url": "https://github.com/btcpayserver/php-bitpay-client.git" 6 | }, 7 | { 8 | "type": "package", 9 | "package": { 10 | "name": "wordpress", 11 | "version": "4.8.2", 12 | "dist": { 13 | "type": "zip", 14 | "url": "https://github.com/WordPress/WordPress/archive/4.8.2.zip" 15 | } 16 | } 17 | } 18 | ], 19 | "require": { 20 | "bitpay/php-client": "dev-master#btcpay-v2.2.23" 21 | }, 22 | "require-dev": { 23 | "wp-cli/wp-cli": "*", 24 | "fabpot/php-cs-fixer": "@stable" 25 | }, 26 | "minimum-stability": "stable", 27 | "config": { 28 | "bin-dir": "bin/" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /woocommerce/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM wordpress:latest 2 | 3 | ENV WOOCOMMERCE_VERSION 4.4.1 4 | 5 | RUN apt-get update \ 6 | && apt-get install -y --no-install-recommends unzip wget \ 7 | && wget https://downloads.wordpress.org/plugin/woocommerce.$WOOCOMMERCE_VERSION.zip -O /tmp/temp.zip \ 8 | && cd /usr/src/wordpress/wp-content/plugins \ 9 | && unzip /tmp/temp.zip \ 10 | && rm /tmp/temp.zip \ 11 | && rm -rf /var/lib/apt/lists/* 12 | 13 | # Install the gmp and mcrypt extensions 14 | RUN apt-get update -y 15 | RUN apt-get install -y libgmp-dev 16 | RUN ln -s /usr/include/x86_64-linux-gnu/gmp.h /usr/local/include/ 17 | RUN docker-php-ext-configure gmp 18 | RUN docker-php-ext-install gmp 19 | 20 | RUN echo extension=gmp.so > $PHP_INI_DIR/conf.d/gmp.ini 21 | 22 | # Download WordPress CLI 23 | RUN curl -L "https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar" > /usr/bin/wp && \ 24 | chmod +x /usr/bin/wp 25 | 26 | VOLUME ["/var/www/html"] -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright for portions of BTCPayService are held by BitPay Inc 2011-2017. 2 | 3 | The MIT License (MIT) 4 | 5 | Copyright (c) 2017-2018 BTCPay, Inc. 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | -------------------------------------------------------------------------------- /src/assets/css/token.css: -------------------------------------------------------------------------------- 1 | @import url("//fonts.googleapis.com/css?family=Ubuntu:400"); 2 | .btcpay-token { 3 | background: #0F3723; 4 | font-family: 'Ubuntu', sans-serif; 5 | color: #fff; 6 | border-left: 4px solid #0F3723; 7 | display: inline-block; 8 | position: relative; 9 | padding-bottom: 1em; 10 | border-radius: 4px; 11 | } 12 | .btcpay-token--hidden { 13 | display: none; 14 | } 15 | .btcpay-token--testnet { 16 | border-color: #cc0; 17 | } 18 | .btcpay-token__prop { 19 | padding: 0 1em; 20 | font-size: 0.85em; 21 | color: #ccddff; 22 | } 23 | .btcpay-token__label { 24 | color: #fff; 25 | display: inline-block; 26 | min-width: 4em; 27 | } 28 | .btcpay-token__header { 29 | margin-bottom: 1em; 30 | margin-top: 0.3em; 31 | white-space: nowrap; 32 | } 33 | .btcpay-token__logo { 34 | width: 5em; 35 | display: inline-block; 36 | box-sizing: border-box; 37 | text-align: center; 38 | margin-right: 3em; 39 | } 40 | .btcpay-token__logo img { 41 | margin-bottom: -13px; 42 | } 43 | .btcpay-token__logo:after { 44 | display: inline; 45 | color: #0f0; 46 | } 47 | .btcpay-token--testnet .btcpay-token__logo:after { 48 | color: #cc0; 49 | } 50 | .btcpay-token__revoke { 51 | display: block; 52 | float: right; 53 | padding: 0.5em 0.75em; 54 | color: #f00; 55 | text-decoration: none; 56 | text-align: right; 57 | border: none; 58 | background: transparent; 59 | cursor: pointer; 60 | } 61 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM php:5.6-cli 2 | 3 | RUN apt-get update && apt-get install -my wget gnupg 4 | 5 | RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - 6 | 7 | RUN apt-get update \ 8 | && apt-get install -y \ 9 | nodejs \ 10 | build-essential \ 11 | npm \ 12 | git \ 13 | libmcrypt-dev \ 14 | && rm -rf /var/lib/apt/lists/* \ 15 | && docker-php-ext-install mcrypt \ 16 | && apt-get remove -y \ 17 | libmcrypt-dev \ 18 | && apt-get install -y \ 19 | libmcrypt4 \ 20 | && apt-get autoremove -y 21 | 22 | 23 | # Let the conatiner know that there is no tty 24 | ENV DEBIAN_FRONTEND noninteractive 25 | ENV COMPOSER_NO_INTERACTION 1 26 | 27 | # RUN ln -s "$(which nodejs)" /usr/bin/node 28 | # Show versions 29 | RUN php -v && node -v && npm -v 30 | 31 | WORKDIR /app 32 | # Install composer 33 | RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer 34 | RUN composer selfupdate 35 | 36 | # Install node tools 37 | RUN npm install -g n && n stable 38 | RUN npm install -g grunt 39 | RUN grunt --version 40 | 41 | RUN docker-php-ext-install bcmath 42 | 43 | COPY composer.json composer.json 44 | RUN php /usr/local/bin/composer install --no-dev 45 | 46 | COPY package.json package.json 47 | RUN npm install 48 | 49 | COPY . . 50 | VOLUME ["/app/dist"] 51 | 52 | ENTRYPOINT ["node_modules/.bin/grunt", "build", "--force"] -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/----bug-report-.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: " \U0001F41B Bug report " 3 | about: " Report a bug or a technical issue " 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | 21 | 22 | **Describe the bug** 23 | 24 | 25 | 26 | 27 | ** Woocommerce System Status ** 28 | 29 | 30 | 31 | 32 | 33 | **WooCommerce Plugin Logs (if applicable)** 34 | 35 | 36 | 37 | 38 | **Your BTCPay Environment (please complete the following information):** 39 | 40 | - BTCPay Server Version: 41 | - Deployment Method: 42 | - Browser: 43 | 44 | 45 | **Additional context** 46 | 47 | 48 | 49 | **Screenshots / Video / GIf (if applicable)** 50 | 51 | 52 | -------------------------------------------------------------------------------- /wp-repo-publish.ps1: -------------------------------------------------------------------------------- 1 | param ( 2 | [string]$distfolder= "./dist/btcpay-for-woocommerce", 3 | [string]$svndir = "./../../Svn/btcpay-for-woocommerce", 4 | [string]$svnrepo = "https://plugins.svn.wordpress.org/btcpay-for-woocommerce", 5 | [string]$svnuser, 6 | [string]$svnpassword 7 | ) 8 | pushd 9 | $match = ([regex] 'Version:\W+(([0-9]+\.?)+)').Match((Get-Content ".\src\class-wc-gateway-btcpay.php")) 10 | if (-not $match.Success) { 11 | Write-Host "Impossible to detect the version" 12 | Exit 13 | } 14 | 15 | $version = $match.Groups[1].Value 16 | 17 | Write-Host "Deploying version $version" 18 | 19 | .\docker-build.ps1 20 | 21 | if ((-not (Test-Path $svndir) -or (-not (Test-Path ($svndir+ "/.svn")))) -and (-not($svnrepo) -or -not($svnuser) -or -not($svnpassword)) ) { 22 | Write-Host "You need to either have a valid svn dir already authenticated or provide svn credentials" -foreground Red 23 | Exit 24 | } 25 | 26 | if (-not (Test-Path $svndir)){ 27 | Write-Host "Creating svn dir at $svndir " -foreground Yellow 28 | New-Item -ItemType Directory -Path $svndir -Force | Out-Null 29 | } 30 | 31 | 32 | 33 | if(-not (Test-Path ($svndir+ "/.svn"))){ 34 | 35 | Write-Host "Checking out svn" -foreground Yellow 36 | svn checkout $svnrepo $svndir 37 | } 38 | 39 | if (-not (Test-Path "$svndir\tags\$version")){ 40 | Write-Host "Creating version dir at $svndir\tags\$version " -foreground Yellow 41 | New-Item -ItemType Directory -Path "$svndir\tags\$version" -Force | Out-Null 42 | } 43 | else { 44 | Write-Host "Dir at $svndir\tags\$version already exists, did you forget to bump the version?" -foreground Red 45 | Exit 46 | } 47 | 48 | Write-Host "Copying to trunk " -foreground Yellow 49 | Copy-Item "$distfolder\*" "$svndir\trunk" -Force -Recurse 50 | 51 | Write-Host "Copying to version " -foreground Yellow 52 | Copy-Item "$distfolder\*" "$svndir\tags\$version" -Force -Recurse 53 | 54 | Write-Host "Copying root readme " -foreground Yellow 55 | Copy-Item "$distfolder\readme.txt" "$svndir\readme.txt" -Force 56 | 57 | Set-Location -Path $svndir 58 | Write-Host "Adding all new files to svn " -foreground Yellow 59 | svn add --force * --auto-props --parents --depth infinity --no-ignore -q 60 | 61 | Write-Host "Comitting" -foreground Yellow 62 | svn commit -m "Bump to $version" 63 | 64 | Write-Host "Pushign to SVN " -foreground Yellow 65 | if(-not($svnuser) -or -not($svnpassword)){ 66 | svn.exe update 67 | } 68 | 69 | svn update --username $svnuser --password $svnpassword 70 | 71 | popd -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license Copyright 2011-2014 BitPay Inc., MIT License 3 | * see https://github.com/bitpay/woocommerce-plugin/blob/master/LICENSE 4 | */ 5 | 6 | 'use strict'; 7 | 8 | module.exports = function(grunt) { 9 | 10 | // Project configuration. 11 | grunt.initConfig({ 12 | pkg: grunt.file.readJSON('package.json'), 13 | clean: { 14 | build: ['dist'], 15 | dev: { 16 | src: ['/var/www/html/woocommerce/wp-content/plugins/btcpay-for-woocommerce/'], 17 | options: { 18 | force: true 19 | } 20 | } 21 | }, 22 | compress: { 23 | build: { 24 | options: { 25 | archive: 'dist/btcpay-for-woocommerce.zip' 26 | }, 27 | files: [{ 28 | expand: true, 29 | cwd: 'dist', 30 | src: ['**'] 31 | }] 32 | } 33 | }, 34 | copy: { 35 | build: { 36 | files: [ 37 | { 38 | expand: true, 39 | cwd: 'src/', 40 | src: ['**/**'], 41 | dest: 'dist/btcpay-for-woocommerce' 42 | }, 43 | { 44 | expand: true, 45 | cwd: 'vendor/bitpay/php-client/src/', 46 | src: ['**/**.*'], 47 | dest: 'dist/btcpay-for-woocommerce/lib' 48 | }, 49 | { 50 | src: 'LICENSE', 51 | dest: 'dist/btcpay-for-woocommerce/license.txt' 52 | } 53 | ] 54 | }, 55 | dev: { 56 | files: [{ 57 | expand: true, 58 | cwd: 'dist/btcpay-for-woocommerce', 59 | src: ['**/**'], 60 | dest: '/var/www/html/woocommerce/wp-content/plugins/btcpay-for-woocommerce/' 61 | }] 62 | } 63 | }, 64 | cssmin: { 65 | build: { 66 | options: { 67 | banner: '/**\n * @license Copyright 2011-2018 BitPay Inc. & BtcPay Inc., MIT License\n * see https://github.com/btcpayserver/woocommerce-plugin/blob/master/LICENSE\n */' 68 | }, 69 | files: { 70 | 'dist/btcpay-for-woocommerce/assets/css/style.css': ['src/assets/css/**.css'] 71 | } 72 | } 73 | }, 74 | phpcsfixer: { 75 | build: { 76 | dir: 'src/' 77 | }, 78 | options: { 79 | bin: 'vendor/bin/php-cs-fixer', 80 | diff: true, 81 | ignoreExitCode: true, 82 | level: 'all', 83 | quiet: true 84 | } 85 | }, 86 | watch: { 87 | scripts: { 88 | files: ['src/**/**.*'], 89 | tasks: ['dev'], 90 | options: { 91 | spawn: false, 92 | atBegin: true 93 | }, 94 | }, 95 | }, 96 | }); 97 | 98 | // Load the plugins 99 | grunt.loadNpmTasks('grunt-contrib-clean'); 100 | grunt.loadNpmTasks('grunt-contrib-compress'); 101 | grunt.loadNpmTasks('grunt-contrib-copy'); 102 | grunt.loadNpmTasks('grunt-contrib-cssmin'); 103 | grunt.loadNpmTasks('grunt-contrib-watch'); 104 | grunt.loadNpmTasks('grunt-php-cs-fixer'); 105 | 106 | // Default task(s). 107 | grunt.registerTask('build', ['phpcsfixer', 'clean:build', 'cssmin:build', 'copy:build', 'compress:build']); 108 | grunt.registerTask('dev', ['build', 'clean:dev', 'copy:dev']); 109 | grunt.registerTask('default', 'build'); 110 | 111 | }; 112 | 113 | -------------------------------------------------------------------------------- /woocommerce/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | dev: 4 | build: . 5 | links: 6 | - mysql 7 | - btcpayserver 8 | ports: 9 | - 8080:80 10 | expose: 11 | - "80" 12 | volumes: 13 | - "./html:/var/www/html" 14 | environment: 15 | WORDPRESS_DB_USER: wordpress 16 | WORDPRESS_DB_PASSWORD: wordpress 17 | 18 | mysql: 19 | image: mariadb 20 | volumes: 21 | - db_data:/var/lib/mysql 22 | environment: 23 | MYSQL_ROOT_PASSWORD: somewordpress 24 | MYSQL_DATABASE: wordpress 25 | MYSQL_USER: wordpress 26 | MYSQL_PASSWORD: wordpress 27 | expose: 28 | - "3306" 29 | volumes: 30 | - "mariadb_datadir:/var/lib/mysql" 31 | 32 | btcpayserver: 33 | image: btcpayserver/btcpayserver:1.0.5.5-altcoins 34 | expose: 35 | - "80" 36 | ports: 37 | - 8081:80 38 | environment: 39 | # BTCPay settings 40 | BTCPAY_POSTGRES: User ID=postgres;Host=postgres;Port=5432;Database=btcpayserverregtest 41 | BTCPAY_NETWORK: regtest 42 | BTCPAY_CHAINS: "btc,ltc" 43 | BTCPAY_BTCEXPLORERURL: http://nbxplorer:32838/ 44 | BTCPAY_LTCEXPLORERURL: http://nbxplorer:32838/ 45 | BTCPAY_BIND: 0.0.0.0:80 46 | 47 | # NGINX settings 48 | VIRTUAL_NETWORK: nginx-proxy 49 | VIRTUAL_PORT: 49392 50 | 51 | links: 52 | - nbxplorer 53 | - postgres 54 | volumes: 55 | - "btcpay_datadir:/datadir" 56 | - "nbxplorer_datadir:/root/.nbxplorer" 57 | 58 | nbxplorer: 59 | image: nicolasdorier/nbxplorer:2.1.42 60 | restart: unless-stopped 61 | ports: 62 | - "32838:32838" 63 | expose: 64 | - "32838" 65 | environment: 66 | NBXPLORER_NETWORK: regtest 67 | NBXPLORER_CHAINS: "btc,ltc" 68 | NBXPLORER_BTCRPCURL: http://bitcoind:43782/ 69 | NBXPLORER_BTCNODEENDPOINT: bitcoind:39388 70 | NBXPLORER_BTCRPCUSER: ceiwHEbqWI83 71 | NBXPLORER_BTCRPCPASSWORD: DwubwWsoo3 72 | NBXPLORER_LTCRPCURL: http://litecoind:43782/ 73 | NBXPLORER_LTCNODEENDPOINT: litecoind:39388 74 | NBXPLORER_LTCRPCUSER: ceiwHEbqWI83 75 | NBXPLORER_LTCRPCPASSWORD: DwubwWsoo3 76 | NBXPLORER_BIND: 0.0.0.0:32838 77 | NBXPLORER_VERBOSE: 1 78 | NBXPLORER_NOAUTH: 1 79 | links: 80 | - bitcoind 81 | - litecoind 82 | 83 | bitcoind: 84 | image: btcpayserver/bitcoin:0.17.0 85 | environment: 86 | BITCOIN_NETWORK: regtest 87 | BITCOIN_EXTRA_ARGS: | 88 | deprecatedrpc=signrawtransaction 89 | rpcuser=ceiwHEbqWI83 90 | rpcpassword=DwubwWsoo3 91 | rpcport=43782 92 | port=39388 93 | whitelist=0.0.0.0/0 94 | zmqpubrawblock=tcp://0.0.0.0:28332 95 | zmqpubrawtx=tcp://0.0.0.0:28333 96 | ports: 97 | - "43782:43782" 98 | - "28332:28332" 99 | expose: 100 | - "43782" # RPC 101 | - "39388" # P2P 102 | - "28332" # ZMQ 103 | - "28333" # ZMQ 104 | volumes: 105 | - "bitcoin_datadir:/data" 106 | 107 | litecoind: 108 | container_name: woocommerce_litecoind 109 | image: nicolasdorier/docker-litecoin:0.16.3 110 | environment: 111 | BITCOIN_EXTRA_ARGS: | 112 | rpcport=43782 113 | regtest=1 114 | port=39388 115 | rpcuser=ceiwHEbqWI83 116 | rpcpassword=DwubwWsoo3 117 | whitelist=0.0.0.0/0 118 | expose: 119 | - "43782" 120 | - "39388" 121 | volumes: 122 | - "litecoin_datadir:/data" 123 | 124 | postgres: 125 | image: postgres:9.6.5 126 | volumes: 127 | - "postgres_datadir:/var/lib/postgresql/data" 128 | 129 | volumes: 130 | postgres_datadir: 131 | litecoin_datadir: 132 | bitcoin_datadir: 133 | nbxplorer_datadir: 134 | btcpay_datadir: 135 | mariadb_datadir: -------------------------------------------------------------------------------- /GUIDE.md: -------------------------------------------------------------------------------- 1 | # Using the BTCPay plugin for WooCommerce 2 | 3 | ## Prerequisites 4 | 5 | * Last Version Tested: Wordpress 4.5.2 WooCommerce 2.5.5 6 | 7 | You must have a BitPay merchant account to use this plugin. It's free to [sign-up for a BitPay merchant account](https://bitpay.com/start). 8 | 9 | 10 | ## Server Requirements 11 | 12 | * [Wordpress](https://wordpress.org/about/requirements/) >= 4.3.1 (Older versions will work, but we do not test against those) 13 | * [WooCommerce](http://docs.woothemes.com/document/server-requirements/) >= 2.4.10 14 | * [GMP](http://php.net/manual/en/book.gmp.php) or [BCMath](http://php.net/manual/en/book.bc.php) You may have to install GMP as most servers do not come with it, but generally BCMath is already included. 15 | * [mcrypt](http://us2.php.net/mcrypt) 16 | * [OpenSSL](http://us2.php.net/openssl) Must be compiled with PHP 17 | * [PHP5 Curl](http://php.net/manual/en/curl.installation.php) Must be compiled with PHP 18 | * PHP >= 5.5 (we tested this on 5.5) 19 | * Be sure to restart apache after the installation: 20 | 21 | ```bash 22 | sudo apachectl restart 23 | ``` 24 | 25 | ## Installation 26 | 27 | ### When Upgrading From Version 1.x to 2.x 28 | 29 | **Please Note:** Merchants who have a previous version of the WooCommerce BitPay Payment Gateway will need to remove it. 30 | This can be done by going to the Wordpress's Adminstration Panels > Plugins. Deactivate the old plugin, then delete it. 31 | 32 | ### When Installing From the Downloadable Archive 33 | 34 | Visit the [Releases](https://github.com/bitpay/woocommerce-plugin/releases) page of this repository and download the latest version. Once this is done, you can just go to Wordpress's Adminstration Panels > Plugins > Add New > Upload Plugin, select the downloaded archive and click Install Now. After the plugin is installed, click on Activate. 35 | 36 | 37 | **WARNING:** It is good practice to backup your database before installing plugins. Please make sure you create backups. 38 | 39 | 40 | ## Configuration 41 | 42 | Configuration can be done using the Administrator section of Wordpress. 43 | Once Logged in, you will find the configuration settings under **WooCommerce > Settings > Checkout > BtcPay**. 44 | Alternatively, you can also get to the configuration settings via Plugins and clicking the Settings link for this plugin. 45 | 46 | ![BitPay Settings](https://raw.githubusercontent.com/btcpayserver/woocommerce-plugin/master/docs/img/admin.png "BtcPay Settings") 47 | 48 | Here your will need to create a [pairing code](https://bitpay.com/api-tokens) using 49 | your BtcPay store ^ account. Once you have a Pairing Code, put the code in the 50 | Pairing Code field: 51 | ![Pairing Code field](https://raw.githubusercontent.com/btcpayserver/woocommerce-plugin/master/docs/img/pairingcode.png "Pairing Code field") 52 | 53 | On success, you'll receive a token: 54 | ![BitPay Token](https://raw.githubusercontent.com/btcpayserver/woocommerce-plugin/master/docs/img/token.png "Bitpay Token") 55 | 56 | **NOTE:** Pairing Codes are only valid for a short period of time. If it expires 57 | before you get to use it, you can always create a new one and pair with it. 58 | 59 | **NOTE:** You will only need to do this once since each time you do this, the 60 | extension will generate public and private keys that are used to identify you 61 | when using the API. 62 | 63 | You are also able to configure how BitPay's IPN (Instant Payment Notifications) 64 | changes the order in your WooCommerce store. 65 | 66 | ![Invoice Settings](https://raw.githubusercontent.com/bitpay/woocommerce-plugin/master/docs/img/ordersettings.png "Invoice Settings") 67 | 68 | Save your changes and you're good to go! 69 | 70 | ## Usage 71 | 72 | Once enabled, your customers will be given the option to pay with Bitcoins. Once 73 | they checkout they are redirected to a full screen BitPay invoice to pay for 74 | the order. 75 | 76 | As a merchant, the orders in your WooCommerce store can be treated as any other 77 | order. You may need to adjust the Invoice Settings depending on your order 78 | fulfillment. 79 | 80 | 81 | ## How to Get Optimal Performance From the Plugin 82 | 83 | It is highly recommended you install the GMP extension for PHP to acheive maximum performance when using this plugin. 84 | 85 | ### Compile PHP with GMP 86 | 87 | [http://php.net/manual/en/gmp.installation.php](http://php.net/manual/en/gmp.installation.php) 88 | 89 | ### Enable Extension 90 | 91 | If the extension has been included with your PHP install, you only need to uncomment the line in the PHP ini configuration file. 92 | 93 | **On Windows:** 94 | 95 | ```ini 96 | ; From 97 | ;extension=php_gmp.dll 98 | ; To 99 | extension=php_gmp.dll 100 | ``` 101 | 102 | **For Ubuntu:** 103 | 104 | ```bash 105 | $ sudo apt-get update 106 | $ sudo apt-get install php5-gmp 107 | $ sudo php5enmod gmp 108 | 109 | # Restart your server 110 | ``` 111 | 112 | **For Other Linux Systems:** 113 | 114 | ```ini 115 | ; From 116 | ;extension=gmp.so 117 | ; To 118 | extension=gmp.so 119 | 120 | # Restart your server 121 | ``` 122 | -------------------------------------------------------------------------------- /src/languages/btcpay-for-woocommerce.pot: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2021 BTCPay 2 | # This file is distributed under the Copyright 2011-2018 BTCPay & BitPay Inc., MIT License. 3 | msgid "" 4 | msgstr "" 5 | "Project-Id-Version: BTCPay for WooCommerce 3.0.12\n" 6 | "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/src\n" 7 | "Last-Translator: FULL NAME \n" 8 | "Language-Team: LANGUAGE \n" 9 | "MIME-Version: 1.0\n" 10 | "Content-Type: text/plain; charset=UTF-8\n" 11 | "Content-Transfer-Encoding: 8bit\n" 12 | "POT-Creation-Date: 2021-06-05T16:53:37+02:00\n" 13 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 14 | "X-Generator: WP-CLI 2.5.0\n" 15 | "X-Domain: btcpay-for-woocommerce\n" 16 | 17 | #. Plugin Name of the plugin 18 | msgid "BTCPay for WooCommerce" 19 | msgstr "" 20 | 21 | #. Plugin URI of the plugin 22 | msgid "https://wordpress.org/plugins/btcpay-for-woocommerce" 23 | msgstr "" 24 | 25 | #. Description of the plugin 26 | msgid "Enable your WooCommerce store to accept Bitcoin with BTCPay." 27 | msgstr "" 28 | 29 | #. Author of the plugin 30 | msgid "BTCPay" 31 | msgstr "" 32 | 33 | #. Author URI of the plugin 34 | msgid "https://github.com/btcpayserver" 35 | msgstr "" 36 | 37 | #: class-wc-gateway-btcpay.php:107 38 | msgid "Proceed to BTCPay" 39 | msgstr "" 40 | 41 | #: class-wc-gateway-btcpay.php:317 42 | msgid "Title" 43 | msgstr "" 44 | 45 | #: class-wc-gateway-btcpay.php:319 46 | msgid "Controls the name of this payment method as displayed to the customer during checkout." 47 | msgstr "" 48 | 49 | #: class-wc-gateway-btcpay.php:320 50 | msgid "Bitcoin" 51 | msgstr "" 52 | 53 | #: class-wc-gateway-btcpay.php:324 54 | msgid "Customer Message" 55 | msgstr "" 56 | 57 | #: class-wc-gateway-btcpay.php:326 58 | msgid "Message to explain how the customer will be paying for the purchase." 59 | msgstr "" 60 | 61 | #: class-wc-gateway-btcpay.php:334 62 | msgid "Invoice pass to \"confirmed\" state after" 63 | msgstr "" 64 | 65 | #: class-wc-gateway-btcpay.php:351 66 | msgid "Debug Log" 67 | msgstr "" 68 | 69 | #: class-wc-gateway-btcpay.php:353 70 | msgid "Enable logging View Logs" 71 | msgstr "" 72 | 73 | #: class-wc-gateway-btcpay.php:355 74 | msgid "Log BTCPay events, such as IPN requests, inside %s" 75 | msgstr "" 76 | 77 | #: class-wc-gateway-btcpay.php:359 78 | msgid "Notification URL" 79 | msgstr "" 80 | 81 | #: class-wc-gateway-btcpay.php:361 82 | msgid "BTCPay will send IPNs for orders to this URL with the BTCPay invoice data" 83 | msgstr "" 84 | 85 | #: class-wc-gateway-btcpay.php:367 86 | msgid "Redirect URL" 87 | msgstr "" 88 | 89 | #: class-wc-gateway-btcpay.php:369 90 | msgid "After paying the BTCPay invoice, users will be redirected back to this URL" 91 | msgstr "" 92 | 93 | #: class-wc-gateway-btcpay.php:375 94 | msgid "Additional token configuration" 95 | msgstr "" 96 | 97 | #: class-wc-gateway-btcpay.php:377 98 | msgid "You can configure additional tokens here, one per line. e.g. \"HAT;Hat Token;promotion\" See documentation for details. Each one will be available as their own payment method." 99 | msgstr "" 100 | 101 | #: class-wc-gateway-btcpay.php:382 102 | msgid "Additional tokens: Enforce payment tokens" 103 | msgstr "" 104 | 105 | #: class-wc-gateway-btcpay.php:384 106 | msgid "Limit default payment methods to listed \"payment\" tokens." 107 | msgstr "" 108 | 109 | #: class-wc-gateway-btcpay.php:387 110 | msgid "This will override the default btcpay payment method (defaults to all supported by BTCPay Server) and enforce to tokens of type \"payment\". This is useful if you want full control on what is available on BTCPay Server payment page." 111 | msgstr "" 112 | 113 | #: class-wc-gateway-btcpay.php:393 114 | msgid "This plugin version is %s and your PHP version is %s. If you need assistance, please come on our chat https://chat.btcpayserver.org. Thank you for using BTCPay!" 115 | msgstr "" 116 | 117 | #: class-wc-gateway-btcpay.php:1173 118 | msgid "BTCPay invoice paid. Awaiting network confirmation and payment completed status." 119 | msgstr "" 120 | 121 | #: class-wc-gateway-btcpay.php:1182 122 | msgid "BTCPay invoice confirmed. Awaiting payment completed status." 123 | msgstr "" 124 | 125 | #: class-wc-gateway-btcpay.php:1194 126 | msgid "BTCPay invoice payment completed. Payment credited to your merchant account." 127 | msgstr "" 128 | 129 | #: class-wc-gateway-btcpay.php:1204 130 | msgid "Bitcoin payment is invalid for this order! The payment was not confirmed by the network within on time. Do not ship the product for this order!" 131 | msgstr "" 132 | 133 | #: class-wc-gateway-btcpay.php:1211 134 | msgid "Bitcoin payment has expired for this order! The payment was not broadcasted before its expiration. Do not ship the product for this order!" 135 | msgstr "" 136 | 137 | #: class-wc-gateway-btcpay.php:1230 138 | msgid "A payment has arrived late for this order!" 139 | msgstr "" 140 | 141 | #: class-wc-gateway-btcpay.php:1231 142 | msgid "A payment has been received after expiration" 143 | msgstr "" 144 | 145 | #: class-wc-gateway-btcpay.php:1238 146 | msgid "The invoice has expired while a partial payment has been sent" 147 | msgstr "" 148 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | | :warning: WARNING | 2 | |:---------------------------| 3 | | **This plugin, based on the legacy BitPay API and has been discontinued and will only receive security updates. While it will continue to work just fine it won't get any new features. We encourage you use our more modern and actively developed [BTCPay for WooCommerce V2](https://wordpress.org/plugins/btcpay-greenfield-for-woocommerce/) plugin that builds on top of the more feature rich BTCPay Server Greenfield API.** | 4 | 5 | 6 | 7 | ## Quick Start Guide 8 | 9 | To get up and running with our plugin quickly, see the GUIDE here: https://docs.btcpayserver.org/integrations/woocommerce 10 | 11 | ## Brief Description 12 | 13 | Add the ability to accept bitcoin in WooCommerce via BTCPayServer. 14 | This plugin is also available through the [wordpress store](https://wordpress.org/plugins/btcpay-for-woocommerce/). 15 | 16 | ## Detail Description 17 | 18 | Bitcoin is a powerful new peer-to-peer platform for the next generation of financial technology. The decentralized nature of the Bitcoin network allows for a highly resilient value transfer infrastructure, and this allows merchants to gain greater profits. 19 | 20 | This is because there are little to no fees for transferring Bitcoins from one person to another. Unlike other payment methods, Bitcoin payments cannot be reversed, so once you are paid you can ship! No waiting days for a payment to clear. 21 | 22 | ## Development 23 | 24 | ### Setup 25 | 26 | * NodeJS & NPM 27 | * Grunt 28 | * Composer 29 | 30 | Clone the repo: 31 | ```bash 32 | $ git clone https://github.com/btcpayserver/woocommerce-plugin 33 | $ cd woocommerce-plugin 34 | ``` 35 | 36 | Install the dependencies: 37 | ```bash 38 | $ npm install 39 | $ curl -sS https://getcomposer.org/installer | php 40 | $ ./composer.phar install 41 | ``` 42 | 43 | ### Build 44 | 45 | Perform the [setup](#Setup), then: 46 | ```bash 47 | $ ./node_modules/.bin/grunt build 48 | # Outputs plugin at dist/woocommerce-plugin 49 | # Outputs plugin archive at dist/woocommerce-plugin.zip 50 | ``` 51 | 52 | ## Support 53 | 54 | ### BTCPay Support 55 | 56 | * Last Version Tested: Wordpress 4.8.1 WooCommerce 3.1.2 57 | * [GitHub Issues](https://github.com/btcpayserver/woocommerce-plugin/issues) 58 | * Open an issue if you are having issues with this plugin. 59 | * [Support](https://docs.btcpayserver.org) 60 | * BTCPay merchant support documentation 61 | 62 | ### WooCommerce Support 63 | 64 | * [Homepage](http://www.woothemes.com/woocommerce/) 65 | * [Documentation](http://docs.woothemes.com) 66 | * [Support](https://support.woothemes.com) 67 | 68 | ## Troubleshooting 69 | 70 | 1. Ensure a valid SSL certificate is installed on your server. Also ensure your root CA cert is updated. If your CA cert is not current, you will see curl SSL verification errors. 71 | 2. Verify that your web server is not blocking POSTs from servers it may not recognize. Double check this on your firewall as well, if one is being used. 72 | 3. Check the version of this plugin against the official plugin repository to ensure you are using the latest version. Your issue might have been addressed in a newer version! See the [Releases](https://github.com/btcpayserver/woocommerce-plugin/releases) page for the latest. 73 | 4. If all else fails, enable debug logging in the plugin options and open an issue or contact the [community](https://github.com/btcpayserver/btcpayserver#-community). 74 | 75 | **TIP**: When contacting support it will help us is you provide: 76 | 77 | * WordPress and WooCommerce Version 78 | * Other plugins you have installed 79 | * Some plugins do not play nice 80 | * Configuration settings for the plugin (Most merchants take screen grabs) 81 | * Any log files that will help 82 | * Web server error logs 83 | * Screen grabs of error message if applicable. 84 | 85 | ## build with docker 86 | 87 | Powershell: 88 | ``` 89 | ./docker-build.ps1 90 | ``` 91 | 92 | Linux: 93 | ``` 94 | rm -rf dist/ 95 | docker build -t woocommerce_btcpay . 96 | docker run -ti -v "`pwd`/dist:/app/dist" --rm woocommerce_btcpay 97 | echo "Output available in `pwd`/dist/btcpay-for-woocommerce.zip" 98 | ``` 99 | 100 | ## Common errors 101 | 102 | ### SSL certificate problem: unable to get local issuer certificate 103 | 104 | This can come in two conditions: 105 | 106 | * Your BTCPayServer is running on a test certificate 107 | * You have not installed root certificates on the wordpress host 108 | 109 | In the first case, please, make sure a valid SSL certificates is installed on your BTCPayServer. You can check this is the case by browsing to the BTCPayServer page, and check there is no browser warnings. 110 | 111 | In the second case run, 112 | 113 | ``` 114 | sudo apt-get install ca-certificates 115 | ``` 116 | 117 | ## Contribute 118 | 119 | Would you like to help with this project? Great! You don't have to be a developer, either. If you've found a bug or have an idea for an improvement, please open an [issue](https://github.com/btcpayserver/woocommerce-plugin/issues) and tell us about it. 120 | 121 | If you *are* a developer wanting contribute an enhancement, bugfix or other patch to this project, please fork this repository and submit a pull request detailing your changes. We review all PRs! 122 | 123 | This open source project is released under the [MIT license](http://opensource.org/licenses/MIT) which means if you would like to use this project's code in your own project you are free to do so. Speaking of, if you have used our code in a cool new project we would like to hear about it! Please get [in contact](https://github.com/btcpayserver/btcpayserver#-community). 124 | 125 | ## License 126 | 127 | Please refer to the [LICENSE](https://github.com/btcpayserver/woocommerce-plugin/blob/master/LICENSE) file that came with this project. 128 | -------------------------------------------------------------------------------- /src/assets/js/pairing.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license Copyright 2011-2014 BitPay Inc., MIT License 3 | * see https://github.com/bitpay/woocommerce-bitpay/blob/master/LICENSE 4 | */ 5 | 6 | 'use strict'; 7 | 8 | (function ( $ ) { 9 | 10 | $(function () { 11 | 12 | /** 13 | * Update the API Token helper link on Network selection 14 | */ 15 | 16 | var isValidUrl = function(url){ 17 | if(typeof url === "string" && (url.indexOf("http://") == 0 || url.indexOf("https://") == 0)){ 18 | return true; 19 | } 20 | return false; 21 | } 22 | 23 | var formatUrl = function(url){ 24 | if(typeof url === "string"){ 25 | return url.replace(/^(.+?)\/*?$/, "$1"); 26 | } 27 | return null; 28 | } 29 | 30 | 31 | var updatePairingLink = function (e) { 32 | var txtPairingUrl = $('.btcpay-url'); 33 | var pairingLinkElement = $('.btcpay-pairing__link'); 34 | // var requestpairingButton = $('.btcpay-pairing__request_pairing'); 35 | 36 | var pairingLinkMessage = $(".btcpay-pairing__link_message") 37 | if(txtPairingUrl.length == 0 ){ 38 | return; 39 | } 40 | 41 | var url = formatUrl(txtPairingUrl.val()); 42 | if(isValidUrl(url)) 43 | { 44 | url = url + "/api-tokens"; 45 | pairingLinkElement 46 | .attr('href', url) 47 | .html(url) 48 | .show(); 49 | // requestpairingButton.show(); 50 | pairingLinkMessage.hide(); 51 | } 52 | else 53 | { 54 | // requestpairingButton.hide(); 55 | pairingLinkElement.hide(); 56 | pairingLinkMessage.show().text('Please enter BTCPay Url first'); 57 | } 58 | }; 59 | 60 | 61 | // var requestPairing = function(){ 62 | 63 | // var pairingLinkElement = $('.btcpay-pairing__link'); 64 | // if(pairingLinkElement.is(":hidden")){ 65 | // return; 66 | // } 67 | // var url = pairingLinkElement.attr("href"); 68 | // var btcpayWindow = window.open(url, "_blank"); 69 | // btcpayWindow.focus(); 70 | 71 | // $(btcpayWindow).on("message", function(e){ 72 | // if(url.indexOf(e.origin) > 0){ 73 | // try{ 74 | // var data = JSON.stringify(e.data); 75 | // if(data && data.event == 'btcpay-pairing-sin' && data.pairingCode){ 76 | // if(pairingCode){ 77 | // btcpayWindow.close(); 78 | // $(".btcpay-pairing__code").val(data.pairingCode); 79 | // $(".btcpay-pairing__find").click(); 80 | // } 81 | // } 82 | // }catch{ 83 | 84 | // } 85 | // } 86 | // }); 87 | // } 88 | 89 | // $('.btcpay-pairing__request_pairing').on('click', requestPairing); 90 | 91 | 92 | updatePairingLink(); 93 | $('#btcpay_api_token_form').on('input', '.btcpay-url', updatePairingLink); 94 | 95 | /** 96 | * Try to pair with BtcPay using an entered pairing code 97 | */ 98 | $('#btcpay_api_token_form').on('click', '.btcpay-pairing__find', function (e) { 99 | 100 | // Don't submit any forms or follow any links 101 | e.preventDefault(); 102 | 103 | // Hide the pairing code form 104 | $('.btcpay-pairing').hide(); 105 | $('.btcpay-pairing').after('
'); 106 | 107 | // Attempt the pair with BtcPay 108 | $.post(BtcPayAjax.ajaxurl, { 109 | 'action': 'btcpay_pair_code', 110 | 'pairing_code': $('.btcpay-pairing__code').val(), 111 | 'url': $('.btcpay-url').val(), 112 | 'pairNonce': BtcPayAjax.pairNonce 113 | }) 114 | .done(function (data) { 115 | 116 | $('.btcpay-pairing__loading').remove(); 117 | 118 | // Make sure the data is valid 119 | if (data && data.sin && data.label) { 120 | 121 | // Set the token values on the template 122 | $('.btcpay-token').removeClass('btcpay-token--livenet').removeClass('btcpay-token--testnet').addClass('btcpay-token--livenet'); 123 | $('.btcpay-token__token-label').text(data.label); 124 | $('.btcpay-token__token-sin').text(data.sin); 125 | 126 | // Display the token and success notification 127 | $('.btcpay-token').hide().removeClass('btcpay-token--hidden').fadeIn(500); 128 | $('.btcpay-pairing__code').val(''); 129 | $('#message').remove(); 130 | $('h2.woo-nav-tab-wrapper').after('

You have been paired with your BtcPay store!

'); 131 | } 132 | // Pairing failed 133 | else if (data && data.success === false) { 134 | $('.btcpay-pairing').show(); 135 | alert(data.data); 136 | } 137 | 138 | }); 139 | }); 140 | 141 | // Revoking Token 142 | $('#btcpay_api_token_form').on('click', '.btcpay-token__revoke', function (e) { 143 | 144 | // Don't submit any forms or follow any links 145 | e.preventDefault(); 146 | 147 | if (confirm('Are you sure you want to revoke the token?')) { 148 | $.post(BtcPayAjax.ajaxurl, { 149 | 'action': 'btcpay_revoke_token', 150 | 'revokeNonce': BtcPayAjax.revokeNonce 151 | }) 152 | .always(function (data) { 153 | $('.btcpay-token').fadeOut(500, function () { 154 | $('.btcpay-pairing').removeClass('.btcpay-pairing--hidden').show(); 155 | $('#message').remove(); 156 | $('h2.woo-nav-tab-wrapper').after('

You have revoked your token!

'); 157 | }); 158 | }); 159 | } 160 | 161 | }); 162 | 163 | }); 164 | 165 | }( jQuery )); 166 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | All notable changes to this project will be documented in this file. 3 | This project adheres to [Semantic Versioning](http://semver.org/). 4 | 5 | ## 3.0.16 6 | 7 | - Updating readme with legacy notice and link to new V2 version. 8 | 9 | ## 3.0.15 10 | 11 | - Fix: the plugin should not restrain the available currencies @NicolasDorier 12 | 13 | ## 3.0.14 14 | 15 | - Fix: the plugin would to work on some domains, due to a https error @ndeet 16 | 17 | ## 3.0.13 18 | - make plugin able to expand BTCPay payment methods as individual woocommerce payment methods (see https://docs.btcpayserver.org/FAQ/FAQ-Integrations/#how-to-configure-additional-token-support) @ndeet 19 | - allow plugin localization @janhn 20 | 21 | ## 3.0.12 22 | - Make the plugin works better with custom order number @dennisreimann @ndeet 23 | 24 | ## 3.0.11 25 | Empty release to make wordpress plugin store know we are still alive 26 | 27 | ## 3.0.10 28 | ### Fixed 29 | - Fix woocommerce admin compatibility 30 | - Add country code in btcpay invoice 31 | 32 | ## 3.0.8 33 | ### Fixed 34 | - Fix bug with Woocommerce Admin plugin 35 | 36 | ## 3.0.7 37 | ### Fixed 38 | - Update php-bitpay-lib 39 | - Fix misleading error messages 40 | - Fix bug on some format of orderId 41 | 42 | ## 3.0.6 43 | ### Fixed 44 | - Fix: Invalid code 0 during pairing on some install 45 | 46 | ## 3.0.5 47 | ### Added 48 | - Pass tax information to BTCPay Server 49 | 50 | ## 3.0.4 51 | ### Fixed 52 | - Fix JS Error on pairing mechanism 53 | ### Added 54 | - Ensure compatibility with Wordpress 5 55 | 56 | ## 3.0.3 57 | ### Fixed 58 | - Remove legacy currency decimal precision checks 59 | 60 | ## 3.0.2 61 | ### Fixed 62 | - Fix float decimal issue 63 | - Make migrator pull from versions before 3.0.1 not 3.1 64 | ## 3.0.1 65 | ### Fixed 66 | - When upgrading from any version smaller than 3.1 and settings are not set, attempt to load older version. Also display a warning prompt in plugins page after it has been activated to double check settings. 67 | 68 | ## 3.0.0 69 | ### Changed 70 | - Rebrand to be properly BTCPay labelled 71 | - Revert to using original Bitpay php lib and used Customnet for btcpay host urls 72 | - Update default order states to more reasonable values 73 | - Prepare plugin for Wordpress Plugin Repository 74 | 75 | ## 2.2.24 76 | ### Fixed 77 | - Bug: In some circumstances the auto update might crash the wordpress dashboard 78 | 79 | ## 2.2.23 80 | ### Fixed 81 | - Setting `Keep store level settings` to `transaction speed` would still override store's setting 82 | ### Added 83 | - Add `low-medium` transaction speed 84 | 85 | ## 2.2.22 86 | ### Fixed 87 | - Fix crash on some stores `Cannot use object of type stdClass as array in...` on the dashboard 88 | 89 | ## 2.2.21 90 | ### Added 91 | - Add `event_invoice_expiredPaidPartial` handling 92 | 93 | ## 2.2.20 94 | ### Fixed 95 | - Do not crash plugin page if update detection fails, be more resilient 96 | 97 | ## 2.2.19 98 | ### Fixed 99 | - Ignore IPN if another payment method for the order has been chosen (#2) 100 | - Can detect new update in plugin page 101 | 102 | ## 2.2.18 103 | ### Fixed 104 | - Ignore IPN if another payment method for the order has been chosen (#2) 105 | 106 | ## 2.2.17 107 | ### Fixed 108 | - Fix a race condition if process_payment called twice 109 | - Can decide to ignore a BTCPay event 110 | 111 | ## 2.2.16 112 | ### Fixed 113 | - Handle 'expired' IPN 114 | - Handle 'invoice_paidAfterExpiration' IPN event 115 | 116 | ## 2.2.15 117 | ### Fixed 118 | - wrong function call resulting in undefined wc_reduce_stock_levels() (#84) 119 | - syntax error in class-wc-gateway-bitpay.php (#80) 120 | - Make sure that if redirect url is redefined, it has order information (#80) 121 | ### Added 122 | - Redirect page displays 'payment successful' even for unpaid invoices (#81) 123 | 124 | 125 | ## [2.2.14] - 2017-12-30 126 | ### Fixed 127 | - Clicking on Proceed to checkout should not empty the cart 128 | 129 | ### Added 130 | - Add BTCPay custom fields to orders 131 | 132 | ## [2.2.13] - 2017-10-19 133 | ### Fixed 134 | - Support BTCPay custom server 135 | 136 | ### Added 137 | - Fix bug where placing an order with decimal less currency like yen was impossible 138 | 139 | ## [2.2.12] - 2017-09-29 140 | ### Fixed 141 | - Removed non-working option to disable BitPay from the BitPay plugin config page 142 | - Populate buyer email when creating BitPay invoice 143 | - WC v3 compatibility fixes 144 | - Change Mcrypt to OpenSSL (#77) 145 | 146 | ### Added 147 | - Improve logging around updating order states 148 | - Present error when mcrypt is not loaded 149 | 150 | ## [2.2.11-beta] - 2016-06-14 151 | ### Fixed 152 | - order_total with certain filters 153 | 154 | ## [2.2.10] - 2016-06-6 155 | ### Fixed 156 | - Use order numbering system for IPN callbacks 157 | 158 | ## [2.2.9] - 2015-12-04 159 | ### Fixed 160 | - Fixed notification URL initialization 161 | 162 | ## [2.2.8] - 2015-11-19 163 | ### Fixed 164 | - Fixed missing API field in config page 165 | 166 | ## [2.2.7] - 2015-05-28 167 | ### Fixed 168 | - Security issue with ajax calls 169 | 170 | ## [2.2.6] - 2015-04-20 171 | ### Added 172 | - New order status setting which also fixes issues with new orders being set to On-Hold and triggering emails 173 | 174 | ## [2.2.5] - 2015-04-02 175 | ### Fixed 176 | - Bundled BitPay PHP Client for releases now includes entire client 177 | 178 | ## [2.2.4] - 2015-03-09 179 | ### Added 180 | - Curl requirement check during activation 181 | - Notification and Redirect URL settings for advanced users 182 | 183 | ### Fixed 184 | - Order States now save correctly to the database 185 | 186 | ## [2.2.3] - 2015-02-24 187 | ### Fixed 188 | - Requirements check doesn't lock up WordPress when WooCommerce is upgraded 189 | 190 | ## [2.2.2] - 2015-01-13 191 | ### Fixed 192 | - Checkout error message when invoice can't be generated 193 | - Admin error message when pairing with BitPay fails 194 | 195 | ## [2.2.1] - 2014-12-10 196 | ### Fixed 197 | - Token pairing label sanitization which caused issues when accented characters or symbols were used 198 | 199 | ## [2.2.0] - 2014-12-05 200 | ### Changed 201 | - More robust debug logging 202 | 203 | ### Fixed 204 | - PHP 5.4 related issues (array literals, api credentials' serialization) 205 | 206 | ## [2.1.0] - 2014-11-28 207 | ### Changed 208 | - Uses newer BitPay Library that no longer solely requires GMP, but can use BCMath as an alternative 209 | 210 | ## [2.0.2] - 2014-11-20 211 | ### Fixed 212 | - Payment method description/message display on checkout 213 | 214 | ## [2.0.1] - 2014-11-19 215 | ### Changed 216 | - Plugin activation fails on presence of old plugin instead of attempting to delete old plugin and also detect GMP requirement. 217 | 218 | ## 2.0.0 - 2014-11-18 219 | ### Changed 220 | - Implements BitPay's new cryptographically secure authentication. 221 | 222 | [unreleased]: https://github.com/bitpay/woocommerce-plugin/compare/v2.2.7...HEAD 223 | [2.2.7]: https://github.com/bitpay/woocommerce-plugin/compare/v2.2.6...v2.2.7 224 | [2.2.6]: https://github.com/bitpay/woocommerce-plugin/compare/v2.2.5...v2.2.6 225 | [2.2.5]: https://github.com/bitpay/woocommerce-plugin/compare/v2.2.4...v2.2.5 226 | [2.2.4]: https://github.com/bitpay/woocommerce-plugin/compare/v2.2.3...v2.2.4 227 | [2.2.3]: https://github.com/bitpay/woocommerce-plugin/compare/v2.2.2...v2.2.3 228 | [2.2.2]: https://github.com/bitpay/woocommerce-plugin/compare/v2.2.1...v2.2.2 229 | [2.2.1]: https://github.com/bitpay/woocommerce-plugin/compare/v2.2.0...v2.2.1 230 | [2.2.0]: https://github.com/bitpay/woocommerce-plugin/compare/v2.1.0...v2.2.0 231 | [2.1.0]: https://github.com/bitpay/woocommerce-plugin/compare/v2.0.2...v2.1.0 232 | [2.0.2]: https://github.com/bitpay/woocommerce-plugin/compare/v2.0.1...v2.0.2 233 | [2.0.1]: https://github.com/bitpay/woocommerce-plugin/compare/v2.0.0...v2.0.1 234 | -------------------------------------------------------------------------------- /src/readme.txt: -------------------------------------------------------------------------------- 1 | === BTCPay for WooCommerce (Legacy) === 2 | Contributors: Kukks,NicolasDorier,bitcoinshirt,ndeet 3 | Tags: bitcoin,cryptocurrency,btcpay,BTCPay Server,btcpayserver, accept bitcoin,bitcoin plugin, bitcoin payment processor, bitcoin e-commerce, Lightning Network, Litecoin 4 | Requires at least: 3.9 5 | Tested up to: 5.9 6 | Requires PHP: 5.6 7 | Stable tag: master 8 | License: MIT 9 | License URI: https://github.com/btcpayserver/woocommerce-plugin/blob/master/LICENSE 10 | 11 | Now discontinued BTCPay Server plugin based on BitPay API. Please use the new [BTCPay for WooCommerce V2](https://wordpress.org/plugins/btcpay-greenfield-for-woocommerce/) instead. 12 | 13 | == Description == 14 | 15 | **NOTE:** 16 | **This plugin, based on the legacy BitPay API and has been discontinued and will only receive security updates. While it will continue to work just fine it won't get any new features. We encourage you use our more modern and actively developed [BTCPay for WooCommerce V2](https://wordpress.org/plugins/btcpay-greenfield-for-woocommerce/) plugin that builds on top of the more feature rich BTCPay Server Greenfield API.** 17 | 18 | BTCPay Server is a free and open-source cryptocurrency payment processor which allows you to receive payments in Bitcoin and altcoins directly, with no fees, transaction cost or a middleman. 19 | 20 | BTCPay is a non-custodial invoicing system which eliminates the involvement of a third-party. Payments with BTCPay go directly to your wallet, which increases the privacy and security. Your private keys are never uploaded to the server. There is no address re-use since each invoice generates a new address deriving from your xpubkey. 21 | 22 | You can run BTCPay as a self-hosted solution on your own server, or use a third-party host. 23 | 24 | The self-hosted solution allows you not only to attach an unlimited number of stores and use the Lightning Network but also become the payment processor for others. 25 | 26 | If you previously used BitPay's plugin, you can very easily migrate and use BTCPay. 27 | 28 | This plugin is a fork of https://github.com/bitpay/woocommerce-plugin which in turn is a fork of https://github.com/jaafit/bitpayWoocommerce. We have modified the plugin in order to support alternative bitpay compliant servers and enhance usability and functionality. This plugin should be able to run alongside the original bitpay plugin. 29 | 30 | * Direct, peer-to-peer Bitcoin and altcoin payments 31 | * No transaction fees (other than mining fees by crypto network itself) 32 | * No processing fees 33 | * No middleman 34 | * No KYC 35 | * User has complete control over private keys 36 | * Enhanced privacy (no address re-use, no IP leaks to third parties) 37 | * Enhanced security 38 | * Self-hosted 39 | * SegWit support 40 | * Lightning Network support (LND and c-lightning) 41 | * Altcoin support 42 | * Full compatibility with BitPay API (easy migration) 43 | * Attach unlimited stores, process payments for friends 44 | * Easy-embeddable Payment buttons 45 | * Point of Sale app 46 | 47 | == Installation == 48 | 49 | This plugin requires Woocommerce. Please make sure you have Woocommerce installed. 50 | 51 | Infographic 52 | 53 | To integrate BTCPay Server into an existing WooCommerce store, follow the steps below. 54 | 55 | ### 1. Install BTCPay WooCommerce Plugin ### 56 | 57 | ### 2. Deploy BTCPay Server ### 58 | 59 | To launch your BTCPay server, you can self-host it, or use a third party host. 60 | 61 | #### 2.1 Self-hosted BTCPay #### 62 | 63 | There are various ways to [launch a self-hosted BTCPay](https://github.com/btcpayserver/btcpayserver-doc#deployment). If you do not have technical knowledge, use the [web-wizard method](https://launchbtcpay.lunanode.com) and follow the video below. 64 | 65 | https://www.youtube.com/watch?v=NjslXYvp8bk 66 | 67 | For the self-hosted solutions, you\'ll have to wait for your node to sync fully before proceeding to step 3. 68 | 69 | #### 2.2 Third-party host #### 70 | 71 | Those who want to test BTCPay out, or are okay with the limitations of a third-party hosting (dependency and privacy, as well as lack of some features) can use a one of many [third-party hosts](ThirdPartyHosting.md). 72 | 73 | The video below shows you how to connect your store to such host. 74 | 75 | https://www.youtube.com/watch?v=IT2K8It3S3o 76 | 77 | ### 3. Pairing the store ### 78 | 79 | BTCPay WooCommerce plugin is a bridge between your server (payment processor) and your e-commerce store. No matter if you\'re using a self-hosted or third-party solution from step 2, the pairing process is identical. 80 | 81 | Go to your store dashboard. WooCommerce > Settings > Payments. Click BTCPay. 82 | 83 | 1. In the field, enter the full URL of your host (including the https) – https://btcpay.mydomain.com 84 | 2. Click on the generated link which will redirect you back to your BTCPay Server. 85 | 3. Click on request pairing 86 | 4. Approve the pairing 87 | 5. Copy the pairing code 88 | 6. Go back to your store and paste the pairing code 89 | 7. Click “Pair” 90 | 8. When you see the image, it means you successfully paired your server and your store. 91 | 92 | The process of pairing a store with BTCPay is explained in a video below, starting at 1:59 93 | 94 | https://youtu.be/IT2K8It3S3o?t=119 95 | 96 | ### 4. Connecting your wallet ### 97 | 98 | No matter if you're using self-hosted or server hosted by a third-party, the process of configuring your wallet is the same. 99 | 100 | https://www.youtube.com/watch?v=xX6LyQej0NQ 101 | 102 | ### 5. Testing the checkout ### 103 | 104 | Making a small test-purchase from your own store, will give you a piece of mind. Always make sure that everything is set up correctly before going live. The final video, guides you through the steps of setting a gap limit in your Electrum wallet and testing the checkout process. 105 | 106 | https://www.youtube.com/watch?v=Fi3pYpzGmmo 107 | 108 | Depending on your business model and store settings, you may want to [configure your order statuses](https://nbitstack.com/t/how-to-set-up-order-statuses-in-woocommerce-and-btcpay/67). 109 | 110 | == Frequently Asked Questions == 111 | 112 | You'll find extensive documentation and answers to many of your questions on [docs.btcpayserver.org](https://docs.btcpayserver.org/). 113 | 114 | == Screenshots == 115 | 116 | 1. The BTCPay Server invoice. Your customers will see this at the checkout. They can pay from their wallet by scanning a QR or copy/pasting it manually into the wallet. 117 | 2. Customizable plugin interface allows store owners to adjust store statuses according to their needs. 118 | 3. Customer will see the pay with Bitcoin button at the checkout.Text can be customized. 119 | 4. Example of sucessfuly paid invoice. 120 | 5. Example of an easy-embeddable HTML donation payment button. 121 | 6. Example of the PoS app you can launch. 122 | 123 | == Changelog == 124 | 125 | ## 3.0.16 126 | 127 | - Updating readme with legacy notice and link to new V2 version. 128 | 129 | ## 3.0.15 130 | 131 | - Fix: the plugin should not restrain the available currencies @NicolasDorier 132 | 133 | ## 3.0.14 134 | 135 | - Fix: the plugin would to work on some domains, due to a https error @ndeet 136 | 137 | ## 3.0.13 138 | - make plugin able to expand BTCPay payment methods as individual woocommerce payment methods (see https://docs.btcpayserver.org/FAQ/FAQ-Integrations/#how-to-configure-additional-token-support) @ndeet 139 | - allow plugin localization @janhn 140 | 141 | ## 3.0.12 142 | - Make the plugin works better with custom order number @dennisreimann @ndeet 143 | 144 | ## 3.0.11 145 | Empty release to make wordpress plugin store know we are still alive 146 | 147 | ## 3.0.10 148 | Fixed 149 | - Fix woocommerce admin compatibility 150 | - Add country code in btcpay invoice 151 | 152 | ## 3.0.8 153 | Fixed 154 | - Fix bug with Woocommerce Admin plugin 155 | 156 | ## 3.0.7 157 | Fixed 158 | - Update php-bitpay-lib 159 | - Fix misleading error messages 160 | - Fix bug on some format of orderId 161 | 162 | = 3.0.6 = 163 | Fixed 164 | - Fix: Invalid code 0 during pairing on some install 165 | 166 | = 3.0.5 = 167 | Added: 168 | - Pass tax information to BTCPay Server 169 | 170 | = 3.0.4 = 171 | Fixed: 172 | - Fix JS Error on pairing mechanism 173 | Added: 174 | - Ensure compatibility with Wordpress 5 175 | 176 | = 3.0.3 = 177 | Fixed: 178 | - Remove legacy currency decimal precision checks 179 | 180 | = 3.0.2 = 181 | Fixed: 182 | - Fix float decimal issue 183 | - Make migrator pull from versions before 3.0.1 not 3.1 184 | 185 | = 3.0.1 = 186 | Changed: 187 | - When upgrading from any version smaller than 3.1 and settings are not set, attempt to load older version. Also display a warning prompt in plugins page after it has been activated to double check settings. 188 | 189 | = 3.0 = 190 | Changed: 191 | - Rebrand to be properly BTCPay labelled 192 | - Revert to using original Bitpay php lib and used Customnet for btcpay host urls 193 | - Update default order states to more reasonable values 194 | - Prepare plugin for Wordpress Plugin Repository 195 | 196 | =2.2.24 = 197 | Fixed 198 | - Bug: In some circumstances the auto update might crash the wordpress dashboard 199 | 200 | = 2.2.23 = 201 | Fixed 202 | - Setting `Keep store level settings` to `transaction speed` would still override store\'s setting 203 | Added 204 | - Add `low-medium` transaction speed 205 | 206 | = 2.2.22 = 207 | Fixed 208 | - Fix crash on some stores `Cannot use object of type stdClass as array in...` on the dashboard 209 | 210 | = 2.2.21 = 211 | Added 212 | - Add `event_invoice_expiredPaidPartial` handling 213 | 214 | = 2.2.20 = 215 | Fixed 216 | - Do not crash plugin page if update detection fails, be more resilient 217 | 218 | = 2.2.19 = 219 | Fixed 220 | - Ignore IPN if another payment method for the order has been chosen (#2) 221 | - Can detect new update in plugin page 222 | 223 | = 2.2.18 = 224 | Fixed 225 | - Ignore IPN if another payment method for the order has been chosen (#2) 226 | 227 | = 2.2.17 = 228 | Fixed 229 | - Fix a race condition if process_payment called twice 230 | - Can decide to ignore a BTCPay event 231 | 232 | = 2.2.16 = 233 | Fixed 234 | - Handle \'expired\' IPN 235 | - Handle \'invoice_paidAfterExpiration\' IPN event 236 | 237 | = Earlier versions = 238 | For the changelog of earlier versions, please refer to https://github.com/btcpayserver/woocommerce-plugin/releases 239 | -------------------------------------------------------------------------------- /src/class-wc-gateway-btcpay.php: -------------------------------------------------------------------------------- 1 | id = 'btcpay'; 105 | $this->icon = plugin_dir_url(__FILE__).'assets/img/icon.png'; 106 | $this->has_fields = false; 107 | $this->order_button_text = __('Proceed to BTCPay', 'btcpay-for-woocommerce'); 108 | $this->method_title = 'BTCPay'; 109 | $this->method_description = 'BTCPay allows you to accept bitcoin payments on your WooCommerce store.'; 110 | 111 | // Load the settings. 112 | $this->init_form_fields(); 113 | $this->init_settings(); 114 | 115 | // Define user set variables 116 | $this->title = $this->get_option('title'); 117 | $this->description = $this->get_option('description'); 118 | $this->order_states = $this->get_option('order_states'); 119 | $this->debug = 'yes' === $this->get_option('debug', 'no'); 120 | 121 | // Define BitPay settings 122 | $this->api_key = get_option('woocommerce_btcpay_key'); 123 | $this->api_pub = get_option('woocommerce_btcpay_pub'); 124 | $this->api_sin = get_option('woocommerce_btcpay_sin'); 125 | $this->api_token = get_option('woocommerce_btcpay_token'); 126 | $this->api_token_label = get_option('woocommerce_btcpay_label'); 127 | $this->api_url = get_option('woocommerce_btcpay_url'); 128 | 129 | // Define debugging & informational settings 130 | $this->debug_php_version = PHP_MAJOR_VERSION . '.' . PHP_MINOR_VERSION; 131 | $this->debug_plugin_version = constant("BTCPAY_VERSION"); 132 | 133 | $this->log('BTCPay Woocommerce payment plugin object constructor called. Plugin is v' . $this->debug_plugin_version . ' and server is PHP v' . $this->debug_php_version); 134 | $this->log(' [Info] $this->api_key = ' . $this->api_key); 135 | $this->log(' [Info] $this->api_pub = ' . $this->api_pub); 136 | $this->log(' [Info] $this->api_sin = ' . $this->api_sin); 137 | $this->log(' [Info] $this->api_token = ' . $this->api_token); 138 | $this->log(' [Info] $this->api_token_label = ' . $this->api_token_label); 139 | $this->log(' [Info] $this->api_url = ' . $this->api_url); 140 | 141 | // Process Credentials 142 | if (false === empty($this->api_key)) { 143 | try { 144 | $this->api_key = $this->btcpay_decrypt($this->api_key); 145 | 146 | if (false === empty($this->api_key)) { 147 | $this->log(' [Info] Private Key decrypted successfully.'); 148 | } else { 149 | $this->log(' [Error] Private Key decrypted successfully BUT the value itself is null or empty!'); 150 | } 151 | } catch (\Exception $e) { 152 | $this->log(' [Error] Private Key corrupt. Message is: ' . $e->getMessage()); 153 | } 154 | } else { 155 | 156 | } 157 | 158 | if (false === empty($this->api_pub)) { 159 | try { 160 | $this->api_pub = $this->btcpay_decrypt($this->api_pub); 161 | 162 | if (false === empty($this->api_pub)) { 163 | $this->log(' [Info] Public Key decrypted successfully.'); 164 | } else { 165 | $this->log(' [Error] Public Key decrypted successfully BUT the value itself is null or empty!'); 166 | } 167 | } catch (\Exception $e) { 168 | $this->log(' [Error] Public Key corrupt. Message is: ' . $e->getMessage()); 169 | } 170 | } 171 | 172 | if (false === empty($this->api_token)) { 173 | try { 174 | $this->api_token = $this->btcpay_decrypt($this->api_token); 175 | 176 | if (true === isset($this->api_token) && false === empty($this->api_token)) { 177 | $this->log(' [Info] API Token decrypted successfully.'); 178 | } else { 179 | $this->log(' [Error] API Token decrypted successfully BUT the value itself is null or empty!'); 180 | } 181 | } catch (\Exception $e) { 182 | $this->log(' [Error] API Token corrupt. Message is: ' . $e->getMessage()); 183 | } 184 | } 185 | 186 | // Check API Credentials 187 | if (!($this->api_key instanceof \Bitpay\PrivateKey)) { 188 | $this->api_key = null; 189 | $this->log(' [Error] The API Key was NOT an instance of PrivateKey! Instead, it appears to be a ' . gettype($this->api_key) . ' value.'); 190 | } 191 | 192 | if (!($this->api_pub instanceof \Bitpay\PublicKey)) { 193 | $this->api_pub = null; 194 | $this->log(' [Error] The Public Key was NOT an instance of PublicKey! Instead, it appears to be a ' . gettype($this->api_pub) . ' value.'); 195 | } 196 | 197 | if (!($this->api_token instanceof \Bitpay\Token)) { 198 | $this->api_token = null; 199 | $this->log(' [Error] The API Token was NOT an instance of Token! Instead, it appears to be a ' . gettype($this->api_token) . ' value.'); 200 | } 201 | 202 | $this->transaction_speed = $this->get_option('transaction_speed'); 203 | $this->log(' [Info] Transaction speed is now set to: ' . $this->transaction_speed); 204 | 205 | // Actions 206 | add_action('woocommerce_update_options_payment_gateways_' . $this->id, array($this, 'process_admin_options')); 207 | add_action('woocommerce_update_options_payment_gateways_' . $this->id, array($this, 'save_order_states')); 208 | 209 | // Valid for use and IPN Callback 210 | if (false === $this->is_valid_for_use()) { 211 | $this->enabled = 'no'; 212 | $this->log(' [Info] The plugin is NOT valid for use!'); 213 | } else { 214 | $this->enabled = 'yes'; 215 | $this->log(' [Info] The plugin is ok to use.'); 216 | add_action('woocommerce_api_wc_gateway_btcpay', array($this, 'ipn_callback')); 217 | } 218 | 219 | // Additional token initialization. 220 | if (btcpay_get_additional_tokens()) { 221 | $this->initialize_additional_tokens(); 222 | } 223 | $this->is_initialized = true; 224 | } 225 | 226 | /** 227 | * Initializes additional tokens if any configured. 228 | */ 229 | public function initialize_additional_tokens() { 230 | if ( $additional_tokens = btcpay_get_additional_tokens() ) { 231 | foreach ( $additional_tokens as $token ) { 232 | 233 | if ( ! class_exists( $token['classname'] ) ) { 234 | // Build the class structure. 235 | $classcode = "class {$token['classname']} extends WC_Gateway_BtcPay { "; 236 | $classcode .= "public \$token_mode;"; 237 | $classcode .= "public \$token_symbol;"; 238 | $classcode .= "public function __construct() { "; 239 | $classcode .= "parent::__construct();"; 240 | $classcode .= "\$this->id = 'btcpay_{$token['symbol']}';"; 241 | $classcode .= "\$this->method_title = 'BTCPay Asset: {$token['symbol']}';"; 242 | $classcode .= "\$this->method_description = 'This is an additional asset managed by BTCPay.';"; 243 | $classcode .= "\$this->title = '{$token['name']}';"; 244 | $classcode .= "\$this->token_mode = '{$token['mode']}';"; 245 | $classcode .= "\$this->token_symbol = '{$token['symbol']}';"; 246 | $classcode .= "\$this->icon = '{$token['icon']}';"; 247 | $classcode .= "\$this->init_settings();"; 248 | $classcode .= "}"; 249 | $classcode .= "public function ipn_callback() { "; 250 | $classcode .= "return;"; 251 | $classcode .= "}"; 252 | $classcode .= "}"; 253 | 254 | // Initialize it on the fly. 255 | eval( $classcode ); 256 | } 257 | } 258 | } 259 | } 260 | 261 | public function is_btcpay_payment_method($order) 262 | { 263 | $actualMethod = ''; 264 | if (method_exists($order, 'get_payment_method')) { 265 | $actualMethod = $order->get_payment_method(); 266 | } else { 267 | $actualMethod = get_post_meta( $order->get_id(), '_payment_method', true ); 268 | } 269 | 270 | return (false !== strpos($actualMethod, 'btcpay')); 271 | } 272 | 273 | public function __destruct() 274 | { 275 | } 276 | 277 | public function is_valid_for_use() 278 | { 279 | // Check that API credentials are set 280 | if (true === is_null($this->api_key) || 281 | true === is_null($this->api_pub) || 282 | true === is_null($this->api_sin) || 283 | true === is_null($this->api_token)) 284 | { 285 | return false; 286 | } 287 | 288 | // Ensure the currency is supported by BitPay 289 | try { 290 | $currency = new \Bitpay\CurrencyUnrestricted(get_woocommerce_currency()); 291 | 292 | if (false === isset($currency) || true === empty($currency)) { 293 | $this->log(' [Error] The BTCPay payment plugin was called to check if it was valid for use but could not instantiate a currency object.'); 294 | throw new \Exception('The BTCPay payment plugin was called to check if it was valid for use but could not instantiate a currency object. Cannot continue!'); 295 | } 296 | } catch (\Exception $e) { 297 | $this->log(' [Error] In is_valid_for_use: ' . $e->getMessage()); 298 | return false; 299 | } 300 | 301 | $this->log(' [Info] Plugin is valid for use.'); 302 | 303 | return true; 304 | } 305 | 306 | /** 307 | * Initialise Gateway Settings Form Fields 308 | */ 309 | public function init_form_fields() 310 | { 311 | $this->log(' [Info] Entered init_form_fields()...'); 312 | $log_file = 'btcpay-' . sanitize_file_name( wp_hash( 'btcpay' ) ) . '-log'; 313 | $logs_href = get_bloginfo('wpurl') . '/wp-admin/admin.php?page=wc-status&tab=logs&log_file=' . $log_file; 314 | 315 | $this->form_fields = array( 316 | 'title' => array( 317 | 'title' => __('Title', 'btcpay-for-woocommerce'), 318 | 'type' => 'text', 319 | 'description' => __('Controls the name of this payment method as displayed to the customer during checkout.', 'btcpay-for-woocommerce'), 320 | 'default' => __('Bitcoin', 'btcpay-for-woocommerce'), 321 | 'desc_tip' => true, 322 | ), 323 | 'description' => array( 324 | 'title' => __('Customer Message', 'btcpay-for-woocommerce'), 325 | 'type' => 'textarea', 326 | 'description' => __('Message to explain how the customer will be paying for the purchase.', 'btcpay-for-woocommerce'), 327 | 'default' => 'You will be redirected to BTCPay to complete your purchase.', 328 | 'desc_tip' => true, 329 | ), 330 | 'api_token' => array( 331 | 'type' => 'api_token' 332 | ), 333 | 'transaction_speed' => array( 334 | 'title' => __('Invoice pass to "confirmed" state after', 'btcpay-for-woocommerce'), 335 | 'type' => 'select', 336 | 'description' => 'An invoice becomes confirmed after the payment has...', 337 | 'options' => array( 338 | 'default' => 'Keep store level configuration', 339 | 'high' => '0 confirmation on-chain', 340 | 'medium' => '1 confirmation on-chain', 341 | 'low-medium' => '2 confirmations on-chain', 342 | 'low' => '6 confirmations on-chain', 343 | ), 344 | 'default' => 'default', 345 | 'desc_tip' => true, 346 | ), 347 | 'order_states' => array( 348 | 'type' => 'order_states' 349 | ), 350 | 'debug' => array( 351 | 'title' => __('Debug Log', 'btcpay-for-woocommerce'), 352 | 'type' => 'checkbox', 353 | 'label' => sprintf(__('Enable logging View Logs', 'btcpay-for-woocommerce'), $logs_href), 354 | 'default' => 'no', 355 | 'description' => sprintf(__('Log BTCPay events, such as IPN requests, inside %s', 'btcpay-for-woocommerce'), wc_get_log_file_path('btcpay')), 356 | 'desc_tip' => true, 357 | ), 358 | 'notification_url' => array( 359 | 'title' => __('Notification URL', 'btcpay-for-woocommerce'), 360 | 'type' => 'url', 361 | 'description' => __('BTCPay will send IPNs for orders to this URL with the BTCPay invoice data', 'btcpay-for-woocommerce'), 362 | 'default' => '', 363 | 'placeholder' => WC()->api_request_url('WC_Gateway_BtcPay'), 364 | 'desc_tip' => true, 365 | ), 366 | 'redirect_url' => array( 367 | 'title' => __('Redirect URL', 'btcpay-for-woocommerce'), 368 | 'type' => 'url', 369 | 'description' => __('After paying the BTCPay invoice, users will be redirected back to this URL', 'btcpay-for-woocommerce'), 370 | 'default' => '', 371 | 'placeholder' => $this->get_return_url(), 372 | 'desc_tip' => true, 373 | ), 374 | 'additional_tokens' => array( 375 | 'title' => __('Additional token configuration', 'btcpay-for-woocommerce'), 376 | 'type' => 'textarea', 377 | 'description' => __('You can configure additional tokens here, one per line. e.g. "HAT;Hat Token;promotion" See documentation for details. Each one will be available as their own payment method.', 'btcpay-for-woocommerce'), 378 | 'default' => '', 379 | 'desc_tip' => true, 380 | ), 381 | 'additional_tokens_limit_payment' => array( 382 | 'title' => __('Additional tokens: Enforce payment tokens', 'btcpay-for-woocommerce'), 383 | 'type' => 'checkbox', 384 | 'label' => __('Limit default payment methods to listed "payment" tokens.', 'btcpay-for-woocommerce'), 385 | 'default' => 'no', 386 | 'value' => 'yes', 387 | 'description' => __('This will override the default btcpay payment method (defaults to all supported by BTCPay Server) and enforce to tokens of type "payment". This is useful if you want full control on what is available on BTCPay Server payment page.', 'btcpay-for-woocommerce'), 388 | 'desc_tip' => true, 389 | ), 390 | 'support_details' => array( 391 | 'title' => __( 'Plugin & Support Information', 'btcpay' ), 392 | 'type' => 'title', 393 | 'description' => sprintf(__('This plugin version is %s and your PHP version is %s. If you need assistance, please come on our chat https://chat.btcpayserver.org. Thank you for using BTCPay!', 'btcpay-for-woocommerce'), constant("BTCPAY_VERSION"), PHP_MAJOR_VERSION . '.' . PHP_MINOR_VERSION), 394 | ), 395 | ); 396 | 397 | $this->log(' [Info] Initialized form fields: ' . var_export($this->form_fields, true)); 398 | $this->log(' [Info] Leaving init_form_fields()...'); 399 | } 400 | 401 | /** 402 | * HTML output for form field type `api_token` 403 | */ 404 | public function generate_api_token_html() 405 | { 406 | $this->log(' [Info] Entered generate_api_token_html()...'); 407 | 408 | ob_start(); 409 | 410 | // TODO: CSS Imports aren't optimal, but neither is this. Maybe include the css to be css-minimized? 411 | wp_enqueue_style('font-awesome', '//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css'); 412 | wp_enqueue_style('btcpay-token', plugins_url('assets/css/style.css', __FILE__)); 413 | wp_enqueue_script('btcpay-pairing', plugins_url('assets/js/pairing.js', __FILE__), array('jquery'), null, true); 414 | wp_localize_script( 'btcpay-pairing', 'BtcPayAjax', array( 415 | 'ajaxurl' => admin_url( 'admin-ajax.php' ), 416 | 'pairNonce' => wp_create_nonce( 'btcpay-pair-nonce' ), 417 | 'revokeNonce' => wp_create_nonce( 'btcpay-revoke-nonce' ) 418 | ) 419 | ); 420 | 421 | $pairing_form = file_get_contents(plugin_dir_path(__FILE__).'templates/pairing.tpl'); 422 | $token_format = file_get_contents(plugin_dir_path(__FILE__).'templates/token.tpl'); 423 | ?> 424 | 425 | API Token: 426 | 427 |
428 | api_token)) { 430 | echo sprintf($pairing_form, 'visible'); 431 | echo sprintf($token_format, 'hidden', plugins_url('assets/img/logo.png', __FILE__),'',''); 432 | } else { 433 | echo sprintf($pairing_form, 'hidden'); 434 | echo sprintf($token_format, 'livenet', plugins_url('assets/img/logo.png', __FILE__), $this->api_token_label, $this->api_sin); 435 | } 436 | 437 | ?> 438 |
439 | 442 | 443 | 444 | log(' [Info] Leaving generate_api_token_html()...'); 447 | 448 | return ob_get_clean(); 449 | } 450 | 451 | /** 452 | * HTML output for form field type `order_states` 453 | */ 454 | public function generate_order_states_html() 455 | { 456 | $this->log(' [Info] Entered generate_order_states_html()...'); 457 | 458 | ob_start(); 459 | 460 | $bp_statuses = array( 461 | 'new'=>'New Order', 462 | 'paid'=>'Paid', 463 | 'confirmed'=>'Confirmed', 464 | 'complete'=>'Complete', 465 | 'invalid'=>'Invalid', 466 | 'expired'=>'Expired', 467 | 'event_invoice_paidAfterExpiration'=>'Paid after expiration', 468 | 'event_invoice_expiredPaidPartial' => 'Expired with partial payment'); 469 | $df_statuses = array( 470 | 'new'=>'wc-pending', 471 | 'paid'=>'wc-on-hold', 472 | 'confirmed'=>'wc-processing', 473 | 'complete'=>'wc-processing', 474 | 'invalid'=>'wc-failed', 475 | 'expired'=>'wc-cancelled', 476 | 'event_invoice_paidAfterExpiration' => 'wc-failed', 477 | 'event_invoice_expiredPaidPartial' => 'wc-failed'); 478 | 479 | $wc_statuses = wc_get_order_statuses(); 480 | $wc_statuses = array('BTCPAY_IGNORE' => '') + $wc_statuses; 481 | ?> 482 | 483 | Order States: 484 | 485 | 486 | $bp_name) { 489 | ?> 490 | 491 | 492 | 515 | 516 | 520 |
493 | 514 |
521 | 522 | 523 | log(' [Info] Leaving generate_order_states_html()...'); 526 | 527 | return ob_get_clean(); 528 | } 529 | 530 | /** 531 | * Save order states 532 | */ 533 | public function save_order_states() 534 | { 535 | $this->log(' [Info] Entered save_order_states()...'); 536 | 537 | $bp_statuses = array( 538 | 'new' => 'New Order', 539 | 'paid' => 'Paid', 540 | 'confirmed' => 'Confirmed', 541 | 'complete' => 'Complete', 542 | 'invalid' => 'Invalid', 543 | 'expired' => 'Expired', 544 | 'event_invoice_paidAfterExpiration' => 'Paid after expiration', 545 | 'event_invoice_expiredPaidPartial' => 'Expired with partial payment' 546 | ); 547 | 548 | $wc_statuses = wc_get_order_statuses(); 549 | 550 | if (true === isset($_POST['woocommerce_btcpay_order_states'])) { 551 | 552 | $bp_settings = get_option('woocommerce_btcpay_settings'); 553 | $order_states = $bp_settings['order_states']; 554 | 555 | foreach ($bp_statuses as $bp_state => $bp_name) { 556 | if (false === isset($_POST['woocommerce_btcpay_order_states'][ $bp_state ])) { 557 | continue; 558 | } 559 | 560 | $wc_state = $_POST['woocommerce_btcpay_order_states'][ $bp_state ]; 561 | 562 | if (true === array_key_exists($wc_state, $wc_statuses)) { 563 | $this->log(' [Info] Updating order state ' . $bp_state . ' to ' . $wc_state); 564 | $order_states[$bp_state] = $wc_state; 565 | } 566 | 567 | } 568 | $bp_settings['order_states'] = $order_states; 569 | update_option('woocommerce_btcpay_settings', $bp_settings); 570 | } 571 | 572 | $this->log(' [Info] Leaving save_order_states()...'); 573 | } 574 | 575 | /** 576 | * Validate API Token 577 | */ 578 | public function validate_api_token_field() 579 | { 580 | return ''; 581 | } 582 | 583 | /** 584 | * Validate Support Details 585 | */ 586 | public function validate_support_details_field() 587 | { 588 | return ''; 589 | } 590 | 591 | /** 592 | * Validate Order States 593 | */ 594 | public function validate_order_states_field() 595 | { 596 | $order_states = $this->get_option('order_states'); 597 | 598 | $order_states_key = $this->plugin_id . $this->id . '_order_states'; 599 | if ( isset( $_POST[ $order_states_key ] ) ) { 600 | $order_states = $_POST[ $order_states_key ]; 601 | } 602 | return $order_states; 603 | } 604 | 605 | /** 606 | * Validate Notification URL 607 | */ 608 | public function validate_url_field($key) 609 | { 610 | $url = $this->get_option($key); 611 | 612 | if ( isset( $_POST[ $this->plugin_id . $this->id . '_' . $key ] ) ) { 613 | if (filter_var($_POST[ $this->plugin_id . $this->id . '_' . $key ], FILTER_VALIDATE_URL) !== false) { 614 | $url = $_POST[ $this->plugin_id . $this->id . '_' . $key ]; 615 | } else { 616 | $url = ''; 617 | } 618 | } 619 | return $url; 620 | } 621 | 622 | /** 623 | * Validate Redirect URL 624 | */ 625 | public function validate_redirect_url_field() 626 | { 627 | $redirect_url = $this->get_option('redirect_url', ''); 628 | 629 | if ( isset( $_POST['woocommerce_btcpay_redirect_url'] ) ) { 630 | if (filter_var($_POST['woocommerce_btcpay_redirect_url'], FILTER_VALIDATE_URL) !== false) { 631 | $redirect_url = $_POST['woocommerce_btcpay_redirect_url']; 632 | } else { 633 | $redirect_url = ''; 634 | } 635 | } 636 | return $redirect_url; 637 | } 638 | 639 | /** 640 | * Output for the order received page. 641 | */ 642 | public function thankyou_page($order_id) 643 | { 644 | $this->log(' [Info] Entered thankyou_page with order_id = ' . $order_id); 645 | 646 | // Remove cart 647 | WC()->cart->empty_cart(); 648 | 649 | // Intentionally blank. 650 | 651 | $this->log(' [Info] Leaving thankyou_page with order_id = ' . $order_id); 652 | } 653 | 654 | public function get_btcpay_redirect($order_id, $client) 655 | { 656 | $redirect = get_post_meta($order_id, 'BTCPay_redirect', true); 657 | if($redirect) 658 | { 659 | $invoice_id = get_post_meta($order_id, 'BTCPay_id', true);; 660 | $invoice = $client->getInvoice($invoice_id); 661 | $status = $invoice->getStatus(); 662 | if($status === 'invalid' || $status === 'expired') 663 | { 664 | $redirect = null; 665 | } 666 | } 667 | return $redirect; 668 | } 669 | 670 | /** 671 | * Process the payment and return the result 672 | * 673 | * @param int $order_id 674 | * @return array 675 | */ 676 | public function process_payment($order_id) 677 | { 678 | $this->log(' [Info] Entered process_payment() with order_id = ' . $order_id . '...'); 679 | 680 | if (true === empty($order_id)) { 681 | $this->log(' [Error] The BTCPay payment plugin was called to process a payment but the order_id was missing.'); 682 | throw new \Exception('The BTCPay payment plugin was called to process a payment but the order_id was missing. Cannot continue!'); 683 | } 684 | 685 | $order = wc_get_order( $order_id); 686 | 687 | if (false === $order) { 688 | $this->log(' [Error] The BTCPay payment plugin was called to process a payment but could not retrieve the order details for order_id ' . $order_id); 689 | throw new \Exception('The BTCPay payment plugin was called to process a payment but could not retrieve the order details for order_id ' . $order_id . '. Cannot continue!'); 690 | } 691 | 692 | // The order number can differ from the internal $order_id, when a custom 693 | // order number plugin is used. It is added as a reference for the user. 694 | $order_number = $order->get_order_number(); 695 | $notification_url = $this->get_option('notification_url', WC()->api_request_url('WC_Gateway_BtcPay')); 696 | $this->log(' [Info] Generating payment form for order ' . $order_id . ' (Order number ' . $order_number . '). Notify URL: ' . $notification_url); 697 | 698 | // Mark new order according to user settings (we're awaiting the payment) 699 | $new_order_states = $this->get_option('order_states'); 700 | $new_order_status = $new_order_states['new']; 701 | $this->log(' [Info] Changing order status to: '.$new_order_status); 702 | 703 | $order->update_status($new_order_status); 704 | $this->log(' [Info] Changed order status result'); 705 | $thanks_link = $this->get_return_url($order); 706 | 707 | $this->log(' [Info] The variable thanks_link = ' . $thanks_link . '...'); 708 | 709 | // Redirect URL & Notification URL 710 | $redirect_url = $this->get_option('redirect_url', $thanks_link); 711 | 712 | if($redirect_url !== $thanks_link) 713 | { 714 | $order_received_len = strlen('order-received'); 715 | if(substr($redirect_url, -$order_received_len) === 'order-received') 716 | { 717 | $this->log('substr($redirect_url, -$order_received_pos) === order-received'); 718 | $redirect_url = $redirect_url . '=' . $order->get_id(); 719 | } 720 | else 721 | { 722 | $redirect_url = add_query_arg( 'order-received', $order->get_id(), $redirect_url); 723 | } 724 | $redirect_url = add_query_arg( 'key', $order->get_order_key(), $redirect_url); 725 | } 726 | 727 | $this->log(' [Info] The variable redirect_url = ' . $redirect_url . '...'); 728 | 729 | $this->log(' [Info] Notification URL is now set to: ' . $notification_url . '...'); 730 | 731 | // Setup the currency 732 | $currency_code = get_woocommerce_currency(); 733 | 734 | $this->log(' [Info] The variable currency_code = ' . $currency_code . '...'); 735 | 736 | $currency = new \Bitpay\Currency($currency_code); 737 | 738 | if (false === isset($currency) && true === empty($currency)) { 739 | $this->log(' [Error] The BTCPay payment plugin was called to process a payment but could not instantiate a Currency object.'); 740 | throw new \Exception('The BTCPay payment plugin was called to process a payment but could not instantiate a Currency object. Cannot continue!'); 741 | } 742 | 743 | // Get a BitPay Client to prepare for invoice creation 744 | $client = new \Bitpay\Client\Client(); 745 | 746 | if (false === isset($client) && true === empty($client)) { 747 | $this->log(' [Error] The BTCPay payment plugin was called to process a payment but could not instantiate a client object.'); 748 | throw new \Exception('The BTCPay payment plugin was called to process a payment but could not instantiate a client object. Cannot continue!'); 749 | } 750 | $url = $this->api_url; 751 | $client->setUri($url); 752 | $this->log(' [Info] Set url to ' . $this->api_url); 753 | 754 | 755 | $curlAdapter = new \Bitpay\Client\Adapter\CurlAdapter(); 756 | 757 | if (false === isset($curlAdapter) || true === empty($curlAdapter)) { 758 | $this->log(' [Error] The BTCPay payment plugin was called to process a payment but could not instantiate a CurlAdapter object.'); 759 | throw new \Exception('The BTCPay payment plugin was called to process a payment but could not instantiate a CurlAdapter object. Cannot continue!'); 760 | } 761 | 762 | $client->setAdapter($curlAdapter); 763 | 764 | if (false === empty($this->api_key)) { 765 | $client->setPrivateKey($this->api_key); 766 | } else { 767 | $this->log(' [Error] The BTCPay payment plugin was called to process a payment but could not set client->setPrivateKey to this->api_key. The empty() check failed!'); 768 | throw new \Exception(' The BTCPay payment plugin was called to process a payment but could not set client->setPrivateKey to this->api_key. The empty() check failed!'); 769 | } 770 | 771 | if (false === empty($this->api_pub)) { 772 | $client->setPublicKey($this->api_pub); 773 | } else { 774 | $this->log(' [Error] The BTCPay payment plugin was called to process a payment but could not set client->setPublicKey to this->api_pub. The empty() check failed!'); 775 | throw new \Exception(' The BTCPay payment plugin was called to process a payment but could not set client->setPublicKey to this->api_pub. The empty() check failed!'); 776 | } 777 | 778 | if (false === empty($this->api_token)) { 779 | $client->setToken($this->api_token); 780 | } else { 781 | $this->log(' [Error] The BTCPay payment plugin was called to process a payment but could not set client->setToken to this->api_token. The empty() check failed!'); 782 | throw new \Exception(' The BTCPay payment plugin was called to process a payment but could not set client->setToken to this->api_token. The empty() check failed!'); 783 | } 784 | 785 | $redirect = $this->get_btcpay_redirect($order_id, $client); 786 | 787 | if($redirect) 788 | { 789 | $this->log(' [Info] Existing BTCPay invoice has already been created, redirecting to it...'); 790 | $this->log(' [Info] Leaving process_payment()...'); 791 | return array( 792 | 'result' => 'success', 793 | 'redirect' => $redirect, 794 | ); 795 | } 796 | 797 | $this->log(' [Info] Key and token empty checks passed. Parameters in client set accordingly...'); 798 | 799 | // Setup the Invoice 800 | $invoice = new \Bitpay\Invoice(); 801 | 802 | if (false === isset($invoice) || true === empty($invoice)) { 803 | $this->log(' [Error] The BTCPay payment plugin was called to process a payment but could not instantiate an Invoice object.'); 804 | throw new \Exception('The BTCPay payment plugin was called to process a payment but could not instantiate an Invoice object. Cannot continue!'); 805 | } else { 806 | $this->log(' [Info] Invoice object created successfully...'); 807 | } 808 | 809 | $order_url = $order->get_edit_order_url(); 810 | 811 | $pos_data = array( 812 | 'WooCommerce' => array( 813 | 'Order ID' => $order_id, 814 | 'Order Number' => $order_number, 815 | 'Order URL' => $order_url, 816 | 'Plugin Version' => constant("BTCPAY_VERSION") 817 | ) 818 | ); 819 | 820 | // Use the order number as BTCPay order id, because the ID shows up as a reference in the invoices list 821 | $invoice->setOrderId((string)$order_number); 822 | $invoice->setPosData(json_encode($pos_data)); 823 | $invoice->setCurrency($currency); 824 | $invoice->setFullNotifications(true); 825 | $invoice->setExtendedNotifications(true); 826 | 827 | // Handle additional tokens and enforce them for invoice payment. 828 | if (!empty($this->token_symbol)) { 829 | $invoice->setPaymentCurrencies(array($this->token_symbol)); 830 | } 831 | 832 | // For the default BTCPay payment method we enforce payment tokens (if enabled). 833 | if ($this->id === 'btcpay') { 834 | $limit_payment_methods = $this->get_option('additional_tokens_limit_payment'); 835 | $payment_tokens = btcpay_get_additional_tokens('payment'); 836 | if ($payment_tokens && $limit_payment_methods === 'yes') { 837 | $invoice->setPaymentCurrencies(array_column($payment_tokens, 'symbol')); 838 | } 839 | } 840 | 841 | // Add a priced item to the invoice 842 | $item = new \Bitpay\Item(); 843 | 844 | if (false === isset($item) || true === empty($item)) { 845 | $this->log(' [Error] The BTCPay payment plugin was called to process a payment but could not instantiate an item object.'); 846 | throw new \Exception('The BTCPay payment plugin was called to process a payment but could not instantiate an item object. Cannot continue!'); 847 | } else { 848 | $this->log(' [Info] Item object created successfully...'); 849 | } 850 | 851 | $order_total = $order->calculate_totals(); 852 | if (!empty($order_total)) { 853 | $order_total = (float)$order_total; 854 | if (!is_float($order_total)) { 855 | throw new \Bitpay\Client\ArgumentException("Price must be formatted as a float ". $order_total); 856 | } 857 | 858 | // For promotion tokens we need to set the price to 1 (per item quantity). 859 | // The idea is that 1 token is like a voucher. 860 | if (!empty($this->token_symbol) && $this->token_mode === 'promotion') { 861 | // Set the invoice currency to the promotion token. 862 | $invoice->setCurrency(new \Bitpay\CurrencyUnrestricted($this->token_symbol)); 863 | // For each of the purchased items quantity we charge 1 token. 864 | $total_quantity = (float) $this->get_order_total_item_quantity($order); 865 | $item->setPrice($total_quantity); 866 | } else { 867 | $item->setPrice($order_total); 868 | } 869 | 870 | $taxIncluded = $order->get_cart_tax(); 871 | $item->setTaxIncluded($taxIncluded); 872 | } else { 873 | $this->log(' [Error] The BTCPay payment plugin was called to process a payment but could not set item->setPrice to $order->calculate_totals(). The empty() check failed!'); 874 | throw new \Exception('The BTCPay payment plugin was called to process a payment but could not set item->setPrice to $order->calculate_totals(). The empty() check failed!'); 875 | } 876 | // Add buyer's email & country code to the invoice 877 | $buyer = new \Bitpay\Buyer(); 878 | $buyer->setEmail($order->get_billing_email()); 879 | $buyer->setCountry($order->get_shipping_country()); 880 | 881 | $invoice->setBuyer($buyer); 882 | $invoice->setItem($item); 883 | 884 | // Add the Redirect and Notification URLs 885 | $invoice->setRedirectUrl($redirect_url); 886 | $invoice->setNotificationUrl($notification_url); 887 | $invoice->setTransactionSpeed($this->transaction_speed); 888 | 889 | try { 890 | $this->log(' [Info] Attempting to generate invoice for ' . $order_id . ' (Order number ' . $order_number . ') ...'); 891 | 892 | $invoice = $client->createInvoice($invoice); 893 | 894 | if (false === isset($invoice) || true === empty($invoice)) { 895 | $this->log(' [Error] The BTCPay payment plugin was called to process a payment but could not instantiate an invoice object.'); 896 | throw new \Exception('The BTCPay payment plugin was called to process a payment but could not instantiate an invoice object. Cannot continue!'); 897 | } else { 898 | $this->log(' [Info] Call to generate invoice was successful: ' . $client->getResponse()->getBody()); 899 | } 900 | } catch (\Exception $e) { 901 | $this->log(' [Error] Error generating invoice for ' . $order_id . ' (Order number ' . $order_number . '), "' . $e->getMessage() . '"'); 902 | error_log($e->getMessage()); 903 | 904 | return array( 905 | 'result' => 'success', 906 | 'messages' => 'Sorry, but Bitcoin checkout with BTCPay does not appear to be working.' 907 | ); 908 | } 909 | 910 | $responseData = json_decode($client->getResponse()->getBody()); 911 | 912 | // If another BTCPay invoice was created before, returns the original one 913 | $redirect = $this->get_btcpay_redirect($order_id, $client); 914 | if($redirect) 915 | { 916 | $this->log(' [Info] Existing BTCPay invoice has already been created, redirecting to it...'); 917 | $this->log(' [Info] Leaving process_payment()...'); 918 | return array( 919 | 'result' => 'success', 920 | 'redirect' => $redirect, 921 | ); 922 | } 923 | 924 | // Store BTCPay meta data 925 | update_post_meta($order_id, 'BTCPay_redirect', $invoice->getUrl()); 926 | update_post_meta($order_id, 'BTCPay_id', $invoice->getId()); 927 | update_post_meta($order_id, 'BTCPay_rate', $invoice->getRate()); 928 | $formattedRate = number_format($invoice->getRate(), wc_get_price_decimals(), wc_get_price_decimal_separator(), wc_get_price_thousand_separator()); 929 | update_post_meta($order_id, 'BTCPay_formatted_rate', $formattedRate); 930 | 931 | $this->update_btcpay($order_id, $responseData); 932 | 933 | // Reduce stock levels 934 | if (function_exists('wc_reduce_stock_levels')) 935 | { 936 | wc_reduce_stock_levels($order_id); 937 | } 938 | else 939 | { 940 | $order->reduce_order_stock(); 941 | } 942 | 943 | $this->log(' [Info] BTCPay invoice assigned ' . $invoice->getId()); 944 | $this->log(' [Info] Leaving process_payment()...'); 945 | 946 | // Redirect the customer to the BitPay invoice 947 | return array( 948 | 'result' => 'success', 949 | 'redirect' => $invoice->getUrl(), 950 | ); 951 | } 952 | 953 | public function ipn_callback() 954 | { 955 | $this->log(' [Info] Entered ipn_callback()...'); 956 | // Retrieve the Invoice ID and Network URL from the supposed IPN data 957 | $post = file_get_contents("php://input"); 958 | 959 | if (true === empty($post)) { 960 | $this->log(' [Error] No post data sent to IPN handler!'); 961 | error_log('[Error] BTCPay plugin received empty POST data for an IPN message.'); 962 | 963 | wp_die('No post data'); 964 | } else { 965 | $this->log(' [Info] The post data sent to IPN handler is present...'); 966 | } 967 | 968 | $json = json_decode($post, true); 969 | $event = ""; 970 | 971 | if(true === array_key_exists('event', $json) && true === array_key_exists('data', $json)) // extended notification type 972 | { 973 | $this->log(' [Info] Event IPN received...'); 974 | $event = $json['event']; 975 | $json = $json['data']; 976 | } 977 | else 978 | { 979 | $this->log(' [Info] Normal IPN received...'); 980 | } 981 | 982 | if (true === empty($json)) { 983 | $this->log(' [Error] Invalid JSON payload sent to IPN handler: ' . $post); 984 | error_log('[Error] BTCPay plugin received an invalid JSON payload sent to IPN handler: ' . $post); 985 | 986 | wp_die('Invalid JSON'); 987 | } else { 988 | $this->log(' [Info] The post data was decoded into JSON...'); 989 | } 990 | 991 | if (false === array_key_exists('id', $json)) { 992 | $this->log(' [Error] No invoice ID present in JSON payload: ' . var_export($json, true)); 993 | error_log('[Error] BTCPay plugin did not receive an invoice ID present in JSON payload: ' . var_export($json, true)); 994 | 995 | wp_die('No Invoice ID'); 996 | } else { 997 | $this->log(' [Info] Invoice ID present in JSON payload...'); 998 | } 999 | 1000 | if (false === array_key_exists('url', $json)) { 1001 | $this->log(' [Error] No invoice URL present in JSON payload: ' . var_export($json, true)); 1002 | error_log('[Error] BTCPay plugin did not receive an invoice URL present in JSON payload: ' . var_export($json, true)); 1003 | 1004 | wp_die('No Invoice URL'); 1005 | } else { 1006 | $this->log(' [Info] Invoice URL present in JSON payload...'); 1007 | } 1008 | 1009 | // Get a BitPay Client to prepare for invoice fetching 1010 | $client = new \Bitpay\Client\Client(); 1011 | 1012 | if (false === isset($client) && true === empty($client)) { 1013 | $this->log(' [Error] The BTCPay payment plugin was called to handle an IPN but could not instantiate a client object.'); 1014 | throw new \Exception('The BTCPay payment plugin was called to handle an IPN but could not instantiate a client object. Cannot continue!'); 1015 | } else { 1016 | $this->log(' [Info] Created new Client object in IPN handler...'); 1017 | } 1018 | 1019 | $url = $this->api_url; 1020 | $client->setUri($url); 1021 | $this->log(' [Info] Set url to ' . $this->api_url); 1022 | 1023 | $curlAdapter = new \Bitpay\Client\Adapter\CurlAdapter(); 1024 | 1025 | if (false === isset($curlAdapter) && true === empty($curlAdapter)) { 1026 | $this->log(' [Error] The BTCPay payment plugin was called to handle an IPN but could not instantiate a CurlAdapter object.'); 1027 | throw new \Exception('The BTCPay payment plugin was called to handle an IPN but could not instantiate a CurlAdapter object. Cannot continue!'); 1028 | } else { 1029 | $this->log(' [Info] Created new CurlAdapter object in IPN handler...'); 1030 | } 1031 | 1032 | // Setting the Adapter param to a new BitPay CurlAdapter object 1033 | $client->setAdapter($curlAdapter); 1034 | 1035 | if (false === empty($this->api_key)) { 1036 | $client->setPrivateKey($this->api_key); 1037 | } else { 1038 | $this->log(' [Error] The BTCPay payment plugin was called to handle an IPN but could not set client->setPrivateKey to this->api_key. The empty() check failed!'); 1039 | throw new \Exception('The BTCPay payment plugin was called to handle an IPN but could not set client->setPrivateKey to this->api_key. The empty() check failed!'); 1040 | } 1041 | 1042 | if (false === empty($this->api_pub)) { 1043 | $client->setPublicKey($this->api_pub); 1044 | } else { 1045 | $this->log(' [Error] The BTCPay payment plugin was called to handle an IPN but could not set client->setPublicKey to this->api_pub. The empty() check failed!'); 1046 | throw new \Exception('The BTCPay payment plugin was called to handle an IPN but could not set client->setPublicKey to this->api_pub. The empty() check failed!'); 1047 | } 1048 | 1049 | if (false === empty($this->api_token)) { 1050 | $client->setToken($this->api_token); 1051 | } else { 1052 | $this->log(' [Error] The BTCPay payment plugin was called to handle an IPN but could not set client->setToken to this->api_token. The empty() check failed!'); 1053 | throw new \Exception('The BTCPay payment plugin was called to handle an IPN but could not set client->setToken to this->api_token. The empty() check failed!'); 1054 | } 1055 | 1056 | $this->log(' [Info] Key and token empty checks passed. Parameters in client set accordingly...'); 1057 | 1058 | // Fetch the invoice from BTCPay Server to update the order 1059 | try { 1060 | $invoice = $client->getInvoice($json['id']); 1061 | 1062 | if (true === isset($invoice) && false === empty($invoice)) { 1063 | $this->log(' [Info] The IPN check appears to be valid.'); 1064 | } else { 1065 | $this->log(' [Error] The IPN check did not pass!'); 1066 | wp_die('Invalid IPN'); 1067 | } 1068 | } catch (\Exception $e) { 1069 | $error_string = 'IPN Check: Can\'t find invoice ' . $json['id'] . ' (Order Number: ' . $json['orderId'] . ')'; 1070 | $this->log(" [Error] $error_string"); 1071 | $this->log(" [Error] " . $e->getMessage()); 1072 | 1073 | wp_die($e->getMessage()); 1074 | } 1075 | 1076 | // The BTCPay order id is the WooCommerce order number, see $invoice->setOrderId in process_payment() 1077 | $order_number = $invoice->getOrderId(); 1078 | 1079 | // Get the actual WooCommerce ID from the meta data, via the BTCPay invoice id. 1080 | $order_query = wc_get_orders(array( 1081 | 'meta_key' => 'BTCPay_id', 1082 | 'meta_value' => $invoice->getId() 1083 | )); 1084 | if (count($order_query) === 1) { 1085 | $order_id = $order_query[0]->get_id(); 1086 | } else { 1087 | // Use the pos data as fallback, see $invoice->setPosData in process_payment() 1088 | // The posData is a string and needs to be JSON decoded separately. 1089 | $posData = json_decode($json['posData'], true); 1090 | $order_id = $posData['WooCommerce']['Order ID']; 1091 | 1092 | $this->log(' [Error] Can\'t find order by BTCPay meta data. Using order ID fallback from posData.'); 1093 | } 1094 | 1095 | $responseData = json_decode($client->getResponse()->getBody()); 1096 | 1097 | if (false === isset($order_id) && true === empty($order_id)) { 1098 | $this->log(' [Error] The BTCPay payment plugin was called to process an IPN message but could not obtain the order ID from the invoice.'); 1099 | throw new \Exception('The BTCPay payment plugin was called to process an IPN message but could not obtain the order ID from the invoice. Cannot continue!'); 1100 | } else { 1101 | $this->log(' [Info] Order ID is: ' . $order_id. ' (Order Number: ' . $order_number . ')'); 1102 | } 1103 | 1104 | $order = wc_get_order($order_id); 1105 | $this->log('$order = ' . $order. 'and order class = ' . get_class($order)); 1106 | 1107 | if (false === $order) { 1108 | $this->log(' [Error] The BTCPay payment plugin was called to process an IPN message but could not retrieve the order details for order_id: "' . $order_id . '". If you use an alternative order numbering system, please see class-wc-gateway-btcpay.php to apply a search filter.'); 1109 | throw new \Exception('The BTCPay payment plugin was called to process an IPN message but could not retrieve the order details for order_id ' . $order_id . '. Cannot continue!'); 1110 | } else { 1111 | $this->log(' [Info] Order details retrieved successfully...'); 1112 | } 1113 | 1114 | if(!$this->is_btcpay_payment_method($order)) 1115 | { 1116 | $this->log(' [Info] Not using btcpay payment method...'); 1117 | $this->log(' [Info] Leaving ipn_callback()...'); 1118 | return; 1119 | } 1120 | 1121 | $expected_invoiceId = get_post_meta($order_id, 'BTCPay_id', true); 1122 | 1123 | if (false === isset($expected_invoiceId) || true === empty($expected_invoiceId)) { 1124 | $this->log(' [Info] Receiving IPN for an order which has no expected invoice ID, ignoring the IPN...'); 1125 | return; 1126 | } 1127 | 1128 | if($expected_invoiceId !== $json['id']) 1129 | { 1130 | $this->log(' [Error] Received IPN for order '. $order_id . ' with BTCPay invoice id ' . $json['id'] . ' while expected BTCPay invoice is ' . $expected_invoiceId); 1131 | throw new \Exception('Received IPN for order '. $order_id . ' with BTCPay invoice id ' . $json['id'] . ' while expected BTCPay invoice is ' . $expected_invoiceId); 1132 | } 1133 | 1134 | $current_status = $order->get_status(); 1135 | 1136 | if (false === isset($current_status) || true === empty($current_status)) { 1137 | $this->log(' [Error] The BTCPay payment plugin was called to process an IPN message but could not obtain the current status from the order.'); 1138 | throw new \Exception('The BTCPay payment plugin was called to process an IPN message but could not obtain the current status from the order. Cannot continue!'); 1139 | } else { 1140 | $this->log(' [Info] The current order status for this order is ' . $current_status); 1141 | } 1142 | 1143 | $order_states = $this->get_option('order_states'); 1144 | 1145 | $new_order_status = $order_states['new']; 1146 | $paid_status = $order_states['paid']; 1147 | $confirmed_status = $order_states['confirmed']; 1148 | $complete_status = $order_states['complete']; 1149 | $invalid_status = $order_states['invalid']; 1150 | $expired_status = $order_states['expired']; 1151 | $event_invoice_paidAfterExpiration = $order_states['event_invoice_paidAfterExpiration']; 1152 | $event_invoice_expiredPaidPartial = $order_states['event_invoice_expiredPaidPartial']; 1153 | 1154 | $checkStatus = $invoice->getStatus(); 1155 | 1156 | if (false === isset($checkStatus) && true === empty($checkStatus)) { 1157 | $this->log(' [Error] The BTCPay payment plugin was called to process an IPN message but could not obtain the current status from the invoice.'); 1158 | throw new \Exception('The BTCPay payment plugin was called to process an IPN message but could not obtain the current status from the invoice. Cannot continue!'); 1159 | } else { 1160 | $this->log(' [Info] The current status for this invoice is ' . $checkStatus); 1161 | } 1162 | 1163 | if($event === "") 1164 | { 1165 | switch ($checkStatus) { 1166 | 1167 | // The "paid" IPN message is received almost 1168 | // immediately after the BitPay invoice is paid. 1169 | case 'paid': 1170 | $this->log(' [Info] This order has not been updated yet so setting new status...'); 1171 | if($paid_status !== 'BTCPAY_IGNORE') 1172 | $order->update_status($paid_status); 1173 | $order->add_order_note(__('BTCPay invoice paid. Awaiting network confirmation and payment completed status.', 'btcpay-for-woocommerce')); 1174 | break; 1175 | 1176 | // The "confirmed" status is sent when the payment is 1177 | // confirmed based on your transaction speed setting. 1178 | case 'confirmed': 1179 | $this->log(' [Info] This order has not been updated yet so setting confirmed status...'); 1180 | if($confirmed_status !== 'BTCPAY_IGNORE') 1181 | $order->update_status($confirmed_status); 1182 | $order->add_order_note(__('BTCPay invoice confirmed. Awaiting payment completed status.', 'btcpay-for-woocommerce')); 1183 | break; 1184 | 1185 | // The complete status is when the Bitcoin network 1186 | // obtains 6 confirmations for this transaction. 1187 | case 'complete': 1188 | 1189 | $this->log(' [Info] This order has not been updated yet so setting complete status...'); 1190 | 1191 | $order->payment_complete(); 1192 | if($complete_status !== 'BTCPAY_IGNORE') 1193 | $order->update_status($complete_status); 1194 | $order->add_order_note(__('BTCPay invoice payment completed. Payment credited to your merchant account.', 'btcpay-for-woocommerce')); 1195 | break; 1196 | 1197 | // This order is invalid for some reason. 1198 | // Either it's a double spend or some other 1199 | // problem occurred. 1200 | case 'invalid': 1201 | 1202 | $this->log(' [Info] This order has a problem so setting "invalid" status...'); 1203 | if($invalid_status !== 'BTCPAY_IGNORE') 1204 | $order->update_status($invalid_status, __('Bitcoin payment is invalid for this order! The payment was not confirmed by the network within on time. Do not ship the product for this order!', 'btcpay-for-woocommerce')); 1205 | break; 1206 | 1207 | case 'expired': 1208 | 1209 | $this->log(' [Info] The invoice is in the "expired" status...'); 1210 | if($expired_status !== 'BTCPAY_IGNORE') 1211 | $order->update_status($expired_status, __('Bitcoin payment has expired for this order! The payment was not broadcasted before its expiration. Do not ship the product for this order!', 'btcpay-for-woocommerce')); 1212 | break; 1213 | 1214 | // There was an unknown message received. 1215 | default: 1216 | 1217 | $this->log(' [Info] IPN response is an unknown message type. See error message below:'); 1218 | $error_string = 'Unhandled invoice status: ' . $invoice->getStatus(); 1219 | $this->log(" [Warning] $error_string"); 1220 | } 1221 | $this->update_btcpay($order_id, $responseData); 1222 | } 1223 | else // is an event 1224 | { 1225 | $this->log(' [Info] Received event: '. $event['code'] . " " . $event['name']); 1226 | if ($event['code'] === 1009) 1227 | { 1228 | $this->log(' [Info] The invoice has received a payment after expiration...'); 1229 | if($event_invoice_paidAfterExpiration !== 'BTCPAY_IGNORE') 1230 | $order->update_status($event_invoice_paidAfterExpiration , __('A payment has arrived late for this order!', 'btcpay-for-woocommerce')); 1231 | $order->add_order_note(__('A payment has been received after expiration', 'btcpay-for-woocommerce')); 1232 | } 1233 | if ($event['code'] === 2000) 1234 | { 1235 | $this->log(' [Info] The invoice has expired while a partial payment has been sent...'); 1236 | if($event_invoice_expiredPaidPartial !== 'BTCPAY_IGNORE') 1237 | $order->update_status($event_invoice_expiredPaidPartial , __('The invoice has expired while a partial payment has been sent')); 1238 | $order->add_order_note(__('The invoice has expired while a partial payment has been sent', 'btcpay-for-woocommerce')); 1239 | } 1240 | } 1241 | $this->log(' [Info] Leaving ipn_callback()...'); 1242 | } 1243 | 1244 | public function update_btcpay($order_id, $responseData) 1245 | { 1246 | update_post_meta($order_id, 'BTCPay_btcPrice', $responseData->data->btcPrice); 1247 | update_post_meta($order_id, 'BTCPay_btcPaid', $responseData->data->btcPaid); 1248 | update_post_meta($order_id, 'BTCPay_BTCaddress', $responseData->data->bitcoinAddress); 1249 | } 1250 | 1251 | public function log($message) 1252 | { 1253 | if (true === isset($this->debug) && 'yes' == $this->debug) { 1254 | if (false === isset($this->logger) || true === empty($this->logger)) { 1255 | $this->logger = new WC_Logger(); 1256 | } 1257 | 1258 | $this->logger->add('btcpay', $message); 1259 | } 1260 | } 1261 | 1262 | public function btcpay_encrypt($data) 1263 | { 1264 | if (false === isset($data) || true === empty($data)) { 1265 | throw new \Exception('The BTCPay payment plugin was called to encrypt data but no data was passed!'); 1266 | } 1267 | 1268 | $this->log(' [Info] Entered btcpay_encrypt...'); 1269 | 1270 | $openssl_ext = new \Bitpay\Crypto\OpenSSLExtension(); 1271 | $fingerprint = sha1(sha1(__DIR__)); 1272 | 1273 | if (true === isset($fingerprint) && 1274 | true === isset($openssl_ext) && 1275 | strlen($fingerprint) > 24) 1276 | { 1277 | $fingerprint = substr($fingerprint, 0, 24); 1278 | 1279 | if (false === isset($fingerprint) || true === empty($fingerprint)) { 1280 | throw new \Exception('The BTCPay payment plugin was called to encrypt data but could not generate a fingerprint parameter!'); 1281 | } 1282 | 1283 | $encrypted = $openssl_ext->encrypt(base64_encode(serialize($data)), $fingerprint, '1234567890123456'); 1284 | 1285 | if (true === empty($encrypted)) { 1286 | throw new \Exception('The BTCPay payment plugin was called to encrypt a serialized object and failed!'); 1287 | } 1288 | 1289 | $this->log(' [Info] Leaving class level btcpay_encrypt...'); 1290 | 1291 | return $encrypted; 1292 | } else { 1293 | $this->log(' [Error] Invalid server fingerprint generated in btcpay_encrypt()'); 1294 | wp_die('Invalid server fingerprint generated'); 1295 | } 1296 | } 1297 | 1298 | public function btcpay_decrypt($encrypted) 1299 | { 1300 | if (false === isset($encrypted) || true === empty($encrypted)) { 1301 | throw new \Exception('The BTCPay payment plugin was called to decrypt data but no data was passed!'); 1302 | } 1303 | 1304 | $this->log(' [Info] Entered class level btcpay_decrypt...'); 1305 | 1306 | $openssl_ext = new \Bitpay\Crypto\OpenSSLExtension(); 1307 | 1308 | $fingerprint = sha1(sha1(__DIR__)); 1309 | 1310 | if (true === isset($fingerprint) && 1311 | true === isset($openssl_ext) && 1312 | strlen($fingerprint) > 24) 1313 | { 1314 | $fingerprint = substr($fingerprint, 0, 24); 1315 | 1316 | if (false === isset($fingerprint) || true === empty($fingerprint)) { 1317 | throw new \Exception('The BTCPay payment plugin was called to decrypt data but could not generate a fingerprint parameter!'); 1318 | } 1319 | 1320 | $decrypted = base64_decode($openssl_ext->decrypt($encrypted, $fingerprint, '1234567890123456')); 1321 | 1322 | // Strict base64 char check 1323 | if (false === base64_decode($decrypted, true)) { 1324 | $this->log(' [Warning] In btcpay_decrypt: data appears to have already been decrypted. Strict base64 check failed.'); 1325 | } else { 1326 | $decrypted = base64_decode($decrypted); 1327 | } 1328 | 1329 | if (true === empty($decrypted)) { 1330 | throw new \Exception('The BTCPay payment plugin was called to unserialize a decrypted object and failed! The decrypt function was called with "' . $encrypted . '"'); 1331 | } 1332 | 1333 | $this->log(' [Info] Leaving class level btcpay_decrypt...'); 1334 | 1335 | return unserialize($decrypted); 1336 | } else { 1337 | $this->log(' [Error] Invalid server fingerprint generated in btcpay_decrypt()'); 1338 | wp_die('Invalid server fingerprint generated'); 1339 | } 1340 | 1341 | } 1342 | 1343 | /** 1344 | * Return the total quantity of the whole order for all line items. 1345 | */ 1346 | public function get_order_total_item_quantity(WC_Order $order) 1347 | { 1348 | $total = 0; 1349 | foreach ($order->get_items() as $item_id => $item ) { 1350 | $total += $item->get_quantity(); 1351 | } 1352 | 1353 | return $total; 1354 | } 1355 | } 1356 | /** 1357 | * Add BTCPay Payment Gateways to WooCommerce 1358 | **/ 1359 | function wc_add_btcpay($methods) 1360 | { 1361 | // Add main BTCPay payment method class. 1362 | $methods[] = 'WC_Gateway_BtcPay'; 1363 | 1364 | // Add additional tokens as separate payment methods. 1365 | if ($additional_tokens = btcpay_get_additional_tokens()) { 1366 | foreach ($additional_tokens as $token) { 1367 | $methods[] = $token['classname']; 1368 | } 1369 | } 1370 | 1371 | return $methods; 1372 | } 1373 | 1374 | /** 1375 | * Check and return any configured additional tokens. 1376 | * 1377 | * @param string $mode 1378 | * Can be 'payment' or 'promotion'. 1379 | * 1380 | * @return array|null 1381 | */ 1382 | function btcpay_get_additional_tokens($mode = null) 1383 | { 1384 | $btcpay_settings = get_option('woocommerce_btcpay_settings', null); 1385 | 1386 | if (!empty($btcpay_settings['additional_tokens'])) { 1387 | $tokens = []; 1388 | $tokens_data = str_getcsv($btcpay_settings['additional_tokens'], "\n"); 1389 | foreach ($tokens_data as $row) { 1390 | $token_config = str_getcsv($row, ";"); 1391 | // If mode is set, only return matching tokens. 1392 | if (isset($mode) && $mode !== $token_config[2]) { 1393 | continue; 1394 | } 1395 | 1396 | // Todo: check/make sure token config is complete. 1397 | $token['symbol'] = sanitize_text_field($token_config[0]); 1398 | $token['name'] = sanitize_text_field($token_config[1]); 1399 | $token['mode'] = sanitize_text_field($token_config[2]); 1400 | $token['icon'] = sanitize_text_field($token_config[3]); 1401 | $token['classname'] = "WC_Gateway_BtcPay_{$token['symbol']}"; 1402 | $tokens[] = $token; 1403 | } 1404 | 1405 | return !empty($tokens) ? $tokens : null; 1406 | } 1407 | 1408 | return null; 1409 | } 1410 | 1411 | add_filter('woocommerce_payment_gateways', 'wc_add_btcpay'); 1412 | 1413 | if (!function_exists('btcpay_log')) { 1414 | function btcpay_log($message) 1415 | { 1416 | $logger = new WC_Logger(); 1417 | $logger->add('btcpay', $message); 1418 | } 1419 | } 1420 | /** 1421 | * Add Settings link to the plugin entry in the plugins menu 1422 | **/ 1423 | add_filter('plugin_action_links', 'btcpay_plugin_action_links', 10, 2); 1424 | 1425 | function btcpay_plugin_action_links($links, $file) 1426 | { 1427 | static $this_plugin; 1428 | 1429 | if (false === isset($this_plugin) || true === empty($this_plugin)) { 1430 | $this_plugin = plugin_basename(__FILE__); 1431 | } 1432 | 1433 | if ($file == $this_plugin) { 1434 | $log_file = 'btcpay-' . sanitize_file_name( wp_hash( 'btcpay' ) ) . '-log'; 1435 | $settings_link = 'Settings'; 1436 | $logs_link = 'Logs'; 1437 | array_unshift($links, $settings_link, $logs_link); 1438 | } 1439 | 1440 | return $links; 1441 | } 1442 | 1443 | // TODO: Try to find a way to make it work within the WC_Gateway_BtcPay class 1444 | add_action('wp_ajax_btcpay_pair_code', 'ajax_btcpay_pair_code'); 1445 | add_action('wp_ajax_btcpay_revoke_token', 'ajax_btcpay_revoke_token'); 1446 | add_action('wp_ajax_btcpay_create_invoice', 'ajax_btcpay_create_invoice'); 1447 | 1448 | function ajax_btcpay_pair_code() 1449 | { 1450 | $nonce = $_POST['pairNonce']; 1451 | if ( ! wp_verify_nonce( $nonce, 'btcpay-pair-nonce' ) ) { 1452 | die ( 'Unauthorized!'); 1453 | } 1454 | 1455 | if ( current_user_can( 'manage_options' ) ) { 1456 | 1457 | if (true === isset($_POST['pairing_code']) && trim($_POST['pairing_code']) !== '') { 1458 | // Validate the Pairing Code 1459 | $pairing_code = trim($_POST['pairing_code']); 1460 | } else { 1461 | wp_send_json_error("Pairing Code is required"); 1462 | return; 1463 | } 1464 | 1465 | if (!preg_match('/^[a-zA-Z0-9]{7}$/', $pairing_code)) { 1466 | wp_send_json_error("Invalid Pairing Code"); 1467 | return; 1468 | } 1469 | 1470 | $url = esc_url_raw($_POST['url']); 1471 | 1472 | if (!filter_var($url, FILTER_VALIDATE_URL) || (substr( $url, 0, 7 ) !== "http://" && substr( $url, 0, 8 ) !== "https://")) { 1473 | wp_send_json_error("Invalid url"); 1474 | return; 1475 | } 1476 | 1477 | // Generate Private Key 1478 | $key = new \Bitpay\PrivateKey(); 1479 | 1480 | if (true === empty($key)) { 1481 | throw new \Exception('The BTCPay payment plugin was called to process a pairing code but could not instantiate a PrivateKey object. Cannot continue!'); 1482 | } 1483 | 1484 | $key->generate(); 1485 | 1486 | // Generate Public Key 1487 | $pub = new \Bitpay\PublicKey(); 1488 | 1489 | if (true === empty($pub)) { 1490 | throw new \Exception('The BTCPay payment plugin was called to process a pairing code but could not instantiate a PublicKey object. Cannot continue!'); 1491 | } 1492 | 1493 | $pub->setPrivateKey($key); 1494 | $pub->generate(); 1495 | 1496 | // Get SIN Format 1497 | $sin = new \Bitpay\SinKey(); 1498 | 1499 | if (true === empty($sin)) { 1500 | throw new \Exception('The BTCPay payment plugin was called to process a pairing code but could not instantiate a SinKey object. Cannot continue!'); 1501 | } 1502 | 1503 | $sin->setPublicKey($pub); 1504 | $sin->generate(); 1505 | 1506 | // Create an API Client 1507 | $client = new \Bitpay\Client\Client(); 1508 | 1509 | if (true === empty($client)) { 1510 | throw new \Exception('The BTCPay payment plugin was called to process a pairing code but could not instantiate a Client object. Cannot continue!'); 1511 | } 1512 | $client->setUri($url); 1513 | $curlAdapter = new \Bitpay\Client\Adapter\CurlAdapter(); 1514 | 1515 | if (true === empty($curlAdapter)) { 1516 | throw new \Exception('The BTCPay payment plugin was called to process a pairing code but could not instantiate a CurlAdapter object. Cannot continue!'); 1517 | } 1518 | 1519 | $client->setAdapter($curlAdapter); 1520 | 1521 | $client->setPrivateKey($key); 1522 | $client->setPublicKey($pub); 1523 | 1524 | // Sanitize label 1525 | $label = preg_replace('/[^a-zA-Z0-9 \-\_\.]/', '', get_bloginfo()); 1526 | $label = substr('WooCommerce - '.$label, 0, 59); 1527 | 1528 | try { 1529 | $token = $client->createToken( 1530 | array( 1531 | 'id' => (string) $sin, 1532 | 'pairingCode' => $pairing_code, 1533 | 'label' => $label, 1534 | ) 1535 | ); 1536 | } catch (\Exception $e) { 1537 | wp_send_json_error($e->getMessage()); 1538 | return; 1539 | } 1540 | 1541 | update_option('woocommerce_btcpay_key', btcpay_encrypt($key)); 1542 | update_option('woocommerce_btcpay_pub', btcpay_encrypt($pub)); 1543 | update_option('woocommerce_btcpay_sin', (string)$sin); 1544 | update_option('woocommerce_btcpay_token', btcpay_encrypt($token)); 1545 | update_option('woocommerce_btcpay_label', $label); 1546 | update_option('woocommerce_btcpay_url', $url); 1547 | 1548 | wp_send_json(array('sin' => (string) $sin, 'label' => $label)); 1549 | } 1550 | exit; 1551 | } 1552 | 1553 | function ajax_btcpay_revoke_token() 1554 | { 1555 | $nonce = $_POST['revokeNonce']; 1556 | if ( ! wp_verify_nonce( $nonce, 'btcpay-revoke-nonce' ) ) { 1557 | die ( 'Unauthorized!'); 1558 | } 1559 | 1560 | if ( current_user_can( 'manage_options' ) ) { 1561 | update_option('woocommerce_btcpay_key', null); 1562 | update_option('woocommerce_btcpay_pub', null); 1563 | update_option('woocommerce_btcpay_sin', null); 1564 | update_option('woocommerce_btcpay_token', null); 1565 | update_option('woocommerce_btcpay_label', null); 1566 | update_option('woocommerce_btcpay_network', 'testnet'); 1567 | 1568 | wp_send_json(array('success'=>'Token Revoked!')); 1569 | } 1570 | exit; 1571 | } 1572 | 1573 | function btcpay_encrypt($data) 1574 | { 1575 | if (false === isset($data) || true === empty($data)) { 1576 | throw new \Exception('The BTCPay payment plugin was called to encrypt data but no data was passed!'); 1577 | } 1578 | 1579 | $openssl_ext = new \Bitpay\Crypto\OpenSSLExtension(); 1580 | $fingerprint = sha1(sha1(__DIR__)); 1581 | 1582 | if (true === isset($fingerprint) && 1583 | true === isset($openssl_ext) && 1584 | strlen($fingerprint) > 24) 1585 | { 1586 | $fingerprint = substr($fingerprint, 0, 24); 1587 | 1588 | if (false === isset($fingerprint) || true === empty($fingerprint)) { 1589 | throw new \Exception('The BTCPay payment plugin was called to encrypt data but could not generate a fingerprint parameter!'); 1590 | } 1591 | 1592 | $encrypted = $openssl_ext->encrypt(base64_encode(serialize($data)), $fingerprint, '1234567890123456'); 1593 | 1594 | if (true === empty($encrypted)) { 1595 | throw new \Exception('The BTCPay payment plugin was called to serialize an encrypted object and failed!'); 1596 | } 1597 | 1598 | return $encrypted; 1599 | } else { 1600 | wp_die('Invalid server fingerprint generated'); 1601 | } 1602 | } 1603 | 1604 | function btcpay_decrypt($encrypted) 1605 | { 1606 | if (false === isset($encrypted) || true === empty($encrypted)) { 1607 | throw new \Exception('The BTCPay payment plugin was called to decrypt data but no data was passed!'); 1608 | } 1609 | $openssl_ext = new \Bitpay\Crypto\OpenSSLExtension(); 1610 | 1611 | $fingerprint = sha1(sha1(__DIR__)); 1612 | 1613 | if (true === isset($fingerprint) && 1614 | true === isset($openssl_ext) && 1615 | strlen($fingerprint) > 24) 1616 | { 1617 | $fingerprint = substr($fingerprint, 0, 24); 1618 | 1619 | if (false === isset($fingerprint) || true === empty($fingerprint)) { 1620 | throw new \Exception('The BTCPay payment plugin was called to decrypt data but could not generate a fingerprint parameter!'); 1621 | } 1622 | 1623 | $decrypted = base64_decode($openssl_ext->decrypt($encrypted, $fingerprint, '1234567890123456')); 1624 | 1625 | // Strict base64 char check 1626 | if (false === base64_decode($decrypted, true)) { 1627 | $error_string .= ' [Warning] In btcpay_decrypt: data appears to have already been decrypted. Strict base64 check failed.'; 1628 | } else { 1629 | $decrypted = base64_decode($decrypted); 1630 | } 1631 | 1632 | if (true === empty($decrypted)) { 1633 | throw new \Exception('The BTCPay payment plugin was called to unserialize a decrypted object and failed! The decrypt function was called with "' . $encrypted . '"'); 1634 | } 1635 | 1636 | return unserialize($decrypted); 1637 | } else { 1638 | wp_die('Invalid server fingerprint generated'); 1639 | } 1640 | } 1641 | 1642 | function action_woocommerce_thankyou_btcpay($order_id) 1643 | { 1644 | $wc_order = wc_get_order($order_id); 1645 | 1646 | if($wc_order === false) { 1647 | return; 1648 | } 1649 | $order_data = $wc_order->get_data(); 1650 | $status = $order_data['status']; 1651 | 1652 | $payment_status = file_get_contents(plugin_dir_path(__FILE__) . 'templates/paymentStatus.tpl'); 1653 | $payment_status = str_replace('{$statusTitle}', _x('Payment Status', 'woocommerce_btcpay'), $payment_status); 1654 | switch ($status) 1655 | { 1656 | case 'on-hold': 1657 | $status_desctiption = _x('Waiting for payment', 'woocommerce_btcpay'); 1658 | break; 1659 | case 'processing': 1660 | $status_desctiption = _x('Payment processing', 'woocommerce_btcpay'); 1661 | break; 1662 | case 'completed': 1663 | $status_desctiption = _x('Payment completed', 'woocommerce_btcpay'); 1664 | break; 1665 | case 'failed': 1666 | $status_desctiption = _x('Payment failed', 'woocommerce_btcpay'); 1667 | break; 1668 | default: 1669 | $status_desctiption = _x(ucfirst($status), 'woocommerce_btcpay'); 1670 | break; 1671 | } 1672 | echo str_replace('{$paymentStatus}', $status_desctiption, $payment_status); 1673 | } 1674 | add_action("woocommerce_thankyou_btcpay", 'action_woocommerce_thankyou_btcpay', 10, 1); 1675 | } 1676 | 1677 | function woocommerce_btcpay_failed_requirements() 1678 | { 1679 | global $wp_version; 1680 | global $woocommerce; 1681 | 1682 | $errors = array(); 1683 | if (extension_loaded('openssl') === false){ 1684 | $errors[] = 'The BTCPay payment plugin requires the OpenSSL extension for PHP in order to function. Please contact your web server administrator for assistance.'; 1685 | } 1686 | // PHP 5.4+ required 1687 | if (true === version_compare(PHP_VERSION, '5.4.0', '<')) { 1688 | $errors[] = 'Your PHP version is too old. The BTCPay payment plugin requires PHP 5.4 or higher to function. Please contact your web server administrator for assistance.'; 1689 | } 1690 | 1691 | // Wordpress 3.9+ required 1692 | if (true === version_compare($wp_version, '3.9', '<')) { 1693 | $errors[] = 'Your WordPress version is too old. The BTCPay payment plugin requires Wordpress 3.9 or higher to function. Please contact your web server administrator for assistance.'; 1694 | } 1695 | 1696 | // WooCommerce required 1697 | if (true === empty($woocommerce)) { 1698 | $errors[] = 'The WooCommerce plugin for WordPress needs to be installed and activated. Please contact your web server administrator for assistance.'; 1699 | }elseif (true === version_compare($woocommerce->version, '2.2', '<')) { 1700 | $errors[] = 'Your WooCommerce version is too old. The BTCPay payment plugin requires WooCommerce 2.2 or higher to function. Your version is '.$woocommerce->version.'. Please contact your web server administrator for assistance.'; 1701 | } 1702 | 1703 | // GMP or BCMath required 1704 | if (false === extension_loaded('gmp') && false === extension_loaded('bcmath')) { 1705 | $errors[] = 'The BTCPay payment plugin requires the GMP or BC Math extension for PHP in order to function. Please contact your web server administrator for assistance.'; 1706 | } 1707 | 1708 | // Curl required 1709 | if (false === extension_loaded('curl')) { 1710 | $errors[] = 'The BTCPay payment plugin requires the Curl extension for PHP in order to function. Please contact your web server administrator for assistance.'; 1711 | } 1712 | 1713 | if (false === empty($errors)) { 1714 | return implode("
\n", $errors); 1715 | } else { 1716 | return false; 1717 | } 1718 | 1719 | } 1720 | 1721 | function extractCustomnetFromUrl($url) 1722 | { 1723 | $component = parse_url($url); 1724 | if(!$component){ 1725 | throw new \Exception('Url was invalid'); 1726 | } 1727 | if(array_key_exists("port",$component) && isset($component["port"])){ 1728 | $port = $component["port"]; 1729 | }else if($component["scheme"] === "http"){ 1730 | $port = 80; 1731 | 1732 | }else if($component["scheme"] === "https"){ 1733 | $port = 443; 1734 | } 1735 | $host = $component["host"]; 1736 | return new \Bitpay\Network\Customnet($host, $port); 1737 | } 1738 | 1739 | // Activating the plugin 1740 | function woocommerce_btcpay_activate() 1741 | { 1742 | // Check for Requirements 1743 | $failed = woocommerce_btcpay_failed_requirements(); 1744 | 1745 | $plugins_url = admin_url('plugins.php'); 1746 | 1747 | // Requirements met, activate the plugin 1748 | if ($failed === false) { 1749 | 1750 | // Deactivate any older versions that might still be present 1751 | $plugins = get_plugins(); 1752 | 1753 | foreach ($plugins as $file => $plugin) { 1754 | if ('Bitpay Woocommerce' === $plugin['Name'] && true === is_plugin_active($file)) { 1755 | deactivate_plugins(plugin_basename(__FILE__)); 1756 | wp_die('BtcPay for WooCommerce requires that the old plugin, Bitpay Woocommerce, is deactivated and deleted.
Return to plugins screen'); 1757 | } 1758 | if ('BTCPay for WooCommerce' === $plugin['Name'] && true === is_plugin_active($file) && (0 > version_compare( $plugin['Version'], '3.0' ))) { 1759 | deactivate_plugins(plugin_basename(__FILE__)); 1760 | wp_die('BtcPay for WooCommerce requires that the 2.x version of this plugin is deactivated.
Return to plugins screen'); 1761 | } 1762 | if ('BTCPay for WooCommerce' === $plugin['Name'] 1763 | && (0 > version_compare( $plugin['Version'], '3.0.1' ))) { 1764 | update_option('woocommerce_btcpay_key', 1765 | get_option( 'woocommerce_btcpay_key', get_option('woocommerce_bitpay_key', null) ) ); 1766 | update_option('woocommerce_btcpay_pub', 1767 | get_option( 'woocommerce_btcpay_pub', get_option('woocommerce_bitpay_pub', null) ) ); 1768 | update_option('woocommerce_btcpay_sin', 1769 | get_option( 'woocommerce_btcpay_sin', get_option('woocommerce_bitpay_sin', null) ) ); 1770 | update_option('woocommerce_btcpay_token', 1771 | get_option( 'woocommerce_btcpay_token', get_option('woocommerce_bitpay_token', null) ) ); 1772 | update_option('woocommerce_btcpay_label', 1773 | get_option( 'woocommerce_btcpay_label', get_option('woocommerce_bitpay_label', null) ) ); 1774 | update_option('woocommerce_btcpay_network', 1775 | get_option( 'woocommerce_btcpay_network', get_option('woocommerce_bitpay_network', null) ) ); 1776 | update_option('woocommerce_btcpay_settings', 1777 | get_option( 'woocommerce_btcpay_settings', get_option('woocommerce_bitpay_settings', null) ) ); 1778 | update_option('woocommerce_btcpay_url', 1779 | get_option( 'woocommerce_btcpay_url', get_option('woocommerce_bitpay_url', null) ) ); 1780 | update_option('woocommerce_btcpay_notification_url', 1781 | get_option( 'woocommerce_btcpay_notification_url', get_option('woocommerce_bitpay_notification_url', null) ) ); 1782 | update_option('woocommerce_btcpay_redirect_url', 1783 | get_option( 'woocommerce_btcpay_redirect_url', get_option('woocommerce_bitpay_redirect_url', null) ) ); 1784 | update_option('woocommerce_btcpay_transaction_speed', 1785 | get_option( 'woocommerce_btcpay_transaction_speed', get_option('woocommerce_bitpay_transaction_speed', null) ) ); 1786 | update_option('woocommerce_btcpay_order_states', 1787 | get_option( 'woocommerce_btcpay_order_states', get_option('woocommerce_bitpay_order_states', null) ) ); 1788 | 1789 | set_transient( 'fx_admin_notice_show_migration_message', true, 5 ); 1790 | } 1791 | } 1792 | update_option('woocommerce_btcpay_version', constant("BTCPAY_VERSION")); 1793 | 1794 | } else { 1795 | // Requirements not met, return an error message 1796 | wp_die($failed . '
Return to plugins screen'); 1797 | } 1798 | } 1799 | 1800 | function fx_admin_notice_show_migration_message(){ 1801 | 1802 | /* Check transient, if available display notice */ 1803 | if( get_transient( 'fx_admin_notice_show_migration_message' ) ){ 1804 | ?> 1805 |
1806 |

The BTCPay Plugin for Woocoomerce has been updated from a 2.x version! 1807 | We have attempted to migrate your settings. Please double check them 1808 | here'?>. 1809 | If you don't see pairing data in your setting, make sure to pair your store again.

1810 |
1811 |