Browse Source

Merge branch 'dev' of https://github.com/v2board/v2board into dev

tokumeikoi 3 years ago
parent
commit
e9c79c1c08

+ 107 - 0
app/Payments/CoinPayments.php

@@ -0,0 +1,107 @@
+<?php
+
+namespace App\Payments;
+
+class CoinPayments {
+    public function __construct($config) {
+        $this->config = $config;
+    }
+
+    public function form()
+    {
+        return [
+            'coinpayments_merchant_id' => [
+                'label' => 'Merchant ID',
+                'description' => '商户 ID,填写您在 Account Settings 中得到的 ID',
+                'type' => 'input',
+            ],
+            'coinpayments_ipn_secret' => [
+                'label' => 'IPN Secret',
+                'description' => '通知密钥,填写您在 Merchant Settings 中自行设置的值',
+                'type' => 'input',
+            ],
+            'coinpayments_currency' => [
+                'label' => '货币代码',
+                'description' => '填写您的货币代码(大写),建议与 Merchant Settings 中的值相同',
+                'type' => 'input',
+            ]
+        ];
+    }
+
+    public function pay($order) {
+
+        // IPN notifications are slow, when the transaction is successful, we should return to the user center to avoid user confusion
+        $parseUrl = parse_url($order['return_url']);
+        $port = isset($parseUrl['port']) ? ":{$parseUrl['port']}" : '';
+        $successUrl = "{$parseUrl['scheme']}://{$parseUrl['host']}{$port}";
+
+        $params = [
+            'cmd' => '_pay_simple',
+            'reset' => 1,
+            'merchant' => $this->config['coinpayments_merchant_id'],
+            'item_name' => $order['trade_no'],
+            'item_number' => $order['trade_no'],
+            'want_shipping' => 0,
+            'currency' => $this->config['coinpayments_currency'],
+            'amountf' => sprintf('%.2f', $order['total_amount'] / 100),
+            'success_url' => $successUrl,
+            'cancel_url' => $order['return_url'],
+            'ipn_url' => $order['notify_url']
+        ];
+
+        $params_string = http_build_query($params);
+
+        return [
+            'type' => 1, // Redirect to url
+            'data' =>  'https://www.coinpayments.net/index.php?' . $params_string,
+            'custom_result' => 'IPN OK'
+        ];
+    }
+
+    public function notify($params) {
+
+        if (!isset($params['merchant']) || $params['merchant'] != trim($this->config['coinpayments_merchant_id'])) {
+            abort(500, 'No or incorrect Merchant ID passed');
+        }
+
+        $headers = getallheaders();
+
+        ksort($params);
+        reset($params);
+        $request = stripslashes(http_build_query($params));
+
+        $headerName = 'Hmac';
+        $signHeader = isset($headers[$headerName]) ? $headers[$headerName] : '';
+
+        $hmac = hash_hmac("sha512", $request, trim($this->config['coinpayments_ipn_secret']));
+
+        // if (!hash_equals($hmac, $signHeader)) {
+        // if ($hmac != $_SERVER['HTTP_HMAC']) { <-- Use this if you are running a version of PHP below 5.6.0 without the hash_equals function
+        //     $this->dieSendMessage(400, 'HMAC signature does not match');
+        // }
+
+        if ($hmac != $signHeader) {
+            abort(400, 'HMAC signature does not match');
+        }
+
+        // HMAC Signature verified at this point, load some variables.
+
+        $status = $params['status'];
+
+        if ($status >= 100 || $status == 2) {
+            // payment is complete or queued for nightly payout, success
+            return [
+                'trade_no' => $params['item_number'],
+                'callback_no' => $params['txn_id']
+            ];
+        } else if ($status < 0) {
+            //payment error, this is usually final but payments will sometimes be reopened if there was no exchange rate conversion or with seller consent
+            abort(500, 'Payment Timed Out or Error');
+        } else {
+            //payment is pending, you can optionally add a note to the order page
+            die('IPN OK: pending');
+        }
+
+    }
+
+}

+ 2 - 2
app/Payments/StripeAlipay.php

@@ -40,7 +40,7 @@ class StripeAlipay {
         $currency = $this->config['currency'];
         $exchange = $this->exchange('CNY', strtoupper($currency));
         if (!$exchange) {
-            abort(500, __('user.order.stripeAlipay.currency_convert_timeout'));
+            abort(500, __('Currency conversion has timed out, please try again later'));
         }
         Stripe::setApiKey($this->config['stripe_sk_live']);
         $source = Source::create([
@@ -58,7 +58,7 @@ class StripeAlipay {
             ]
         ]);
         if (!$source['redirect']['url']) {
-            abort(500, __('user.order.stripeAlipay.gateway_request_failed'));
+            abort(500, __('Payment gateway request failed'));
         }
         return [
             'type' => 1,

+ 3 - 3
app/Payments/StripeCredit.php

@@ -46,7 +46,7 @@ class StripeCredit {
         $currency = $this->config['currency'];
         $exchange = $this->exchange('CNY', strtoupper($currency));
         if (!$exchange) {
-            abort(500, __('user.order.stripeCard.currency_convert_timeout'));
+            abort(500, __('Currency conversion has timed out, please try again later'));
         }
         Stripe::setApiKey($this->config['stripe_sk_live']);
         try {
@@ -62,10 +62,10 @@ class StripeCredit {
             ]);
         } catch (\Exception $e) {
             info($e);
-            abort(500, __('user.order.stripeCard.was_problem'));
+            abort(500, __('Payment failed. Please check your credit card information'));
         }
         if (!$charge->paid) {
-            abort(500, __('user.order.stripeCard.deduction_failed'));
+            abort(500, __('Payment failed. Please check your credit card information'));
         }
         return [
             'type' => 2,

+ 2 - 2
app/Payments/StripeWepay.php

@@ -40,7 +40,7 @@ class StripeWepay {
         $currency = $this->config['currency'];
         $exchange = $this->exchange('CNY', strtoupper($currency));
         if (!$exchange) {
-            abort(500, __('user.order.stripeAlipay.currency_convert_timeout'));
+            abort(500, __('Currency conversion has timed out, please try again later'));
         }
         Stripe::setApiKey($this->config['stripe_sk_live']);
         $source = Source::create([
@@ -58,7 +58,7 @@ class StripeWepay {
             ]
         ]);
         if (!$source['wechat']['qr_code_url']) {
-            abort(500, __('user.order.stripeWepay.gateway_request_failed'));
+            abort(500, __('Payment gateway request failed'));
         }
         return [
             'type' => 0,

+ 10 - 10
resources/lang/zh-CN.json

@@ -37,11 +37,11 @@
     "Cancel failed": "取消失败",
     "Currency conversion has timed out, please try again later": "货币转换超时,请稍后再试",
     "Payment gateway request failed": "支付网关请求失败",
-    "Oops, there's a problem... Please refresh the page and try again later": "了点问题,请刷新页面稍后再试",
+    "Oops, there's a problem... Please refresh the page and try again later": "出现了点问题,请刷新页面稍后再试",
     "Payment failed. Please check your credit card information": "扣款失败,请检查信用卡信息",
     "Article does not exist": "文章不存在",
     "No active subscription. Unable to use our provided Apple ID": "无有效订阅,无法使用本站提供的 AppleID",
-    "You must have a valid subscription to view content in this area": "必须拥有有效的订阅才可以查看该区域的内容",
+    "You must have a valid subscription to view content in this area": "必须拥有有效的订阅才可以查看该区域的内容",
     "The maximum number of creations has been reached": "已达到创建数量上限",
     "Coupon cannot be empty": "优惠券不能为空",
     "This coupon is no longer available": "优惠券已无可用次数",
@@ -56,16 +56,16 @@
     "You must use the invitation code to register": "必须使用邀请码才可以注册",
     "Email verification code cannot be empty": "邮箱验证码不能为空",
     "Incorrect email verification code": "邮箱验证码有误",
-    "Email already exists": "邮箱已在系统中",
+    "Email already exists": "邮箱已在系统中存在",
     "Invalid invitation code": "邀请码无效",
     "Register failed": "注册失败",
     "Incorrect email or password": "邮箱或密码错误",
     "Your account has been suspended": "该账户已被停止使用",
     "Token error": "令牌有误",
     "This email is not registered in the system": "该邮箱不存在系统中",
-    "Email verification code has been sent, please request again later": "验证码已发送,请过一会再请求",
+    "Email verification code has been sent, please request again later": "验证码已发送,请过一会再请求",
     "Email verification code": "邮箱验证码",
-    "Plan ID cannot be empty": "套餐ID不能为空",
+    "Plan ID cannot be empty": "套餐 ID 不能为空",
     "Plan period cannot be empty": "套餐周期不能为空",
     "Wrong plan period": "套餐周期参数有误",
     "Ticket subject cannot be empty": "工单主题不能为空",
@@ -75,7 +75,7 @@
     "The withdrawal account cannot be empty": "提现账号不能为空",
     "Old password cannot be empty": "旧密码不能为空",
     "New password cannot be empty": "新密码不能为空",
-    "Password must be greater than 8 digits": "密码必须大于8个字符",
+    "Password must be greater than 8 digits": "密码必须大于 8 个字符",
     "The transfer amount cannot be empty": "划转金额不能为空",
     "The transfer amount parameter is wrong": "划转金额参数有误",
     "Incorrect format of expiration reminder": "过期提醒参数有误",
@@ -83,8 +83,8 @@
     "Email can not be empty": "邮箱不能为空",
     "Email format is incorrect": "邮箱格式不正确",
     "Password can not be empty": "密码不能为空",
-    "The traffic usage in :app_name has reached 80%": "在:app_name的流量使用已达到80%",
-    "The service in :app_name is about to expire": "在:app_name的服务即将到期",
-    "The coupon can only be used :limit_use_with_user per person": "该优惠券每人只能用:limit_use_with_user次",
-    "The coupon code cannot be used for this period": "该优惠券无法用于这个付款周期"
+    "The traffic usage in :app_name has reached 80%": "在 :app_name 已用流量已达到 80%",
+    "The service in :app_name is about to expire": "在 :app_name 的服务即将到期",
+    "The coupon can only be used :limit_use_with_user per person": "该优惠券每人只能用 :limit_use_with_user 次",
+    "The coupon code cannot be used for this period": "此优惠券无法用于该付款周期"
 }