mirror of
https://github.com/lkddi/Xboard.git
synced 2026-04-24 03:57:27 +08:00
Initial commit
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* 自己写别抄,抄NMB抄
|
||||
*/
|
||||
namespace App\Payments;
|
||||
|
||||
class AlipayF2F {
|
||||
public function __construct($config)
|
||||
{
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
public function form()
|
||||
{
|
||||
return [
|
||||
'app_id' => [
|
||||
'label' => '支付宝APPID',
|
||||
'description' => '',
|
||||
'type' => 'input',
|
||||
],
|
||||
'private_key' => [
|
||||
'label' => '支付宝私钥',
|
||||
'description' => '',
|
||||
'type' => 'input',
|
||||
],
|
||||
'public_key' => [
|
||||
'label' => '支付宝公钥',
|
||||
'description' => '',
|
||||
'type' => 'input',
|
||||
],
|
||||
'product_name' => [
|
||||
'label' => '自定义商品名称',
|
||||
'description' => '将会体现在支付宝账单中',
|
||||
'type' => 'input'
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function pay($order)
|
||||
{
|
||||
try {
|
||||
$gateway = new \Library\AlipayF2F();
|
||||
$gateway->setMethod('alipay.trade.precreate');
|
||||
$gateway->setAppId($this->config['app_id']);
|
||||
$gateway->setPrivateKey($this->config['private_key']); // 可以是路径,也可以是密钥内容
|
||||
$gateway->setAlipayPublicKey($this->config['public_key']); // 可以是路径,也可以是密钥内容
|
||||
$gateway->setNotifyUrl($order['notify_url']);
|
||||
$gateway->setBizContent([
|
||||
'subject' => $this->config['product_name'] ?? (admin_setting('app_name', 'XBoard') . ' - 订阅'),
|
||||
'out_trade_no' => $order['trade_no'],
|
||||
'total_amount' => $order['total_amount'] / 100
|
||||
]);
|
||||
$gateway->send();
|
||||
return [
|
||||
'type' => 0, // 0:qrcode 1:url
|
||||
'data' => $gateway->getQrCodeUrl()
|
||||
];
|
||||
} catch (\Exception $e) {
|
||||
abort(500, $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function notify($params)
|
||||
{
|
||||
if ($params['trade_status'] !== 'TRADE_SUCCESS') return false;
|
||||
$gateway = new \Library\AlipayF2F();
|
||||
$gateway->setAppId($this->config['app_id']);
|
||||
$gateway->setPrivateKey($this->config['private_key']); // 可以是路径,也可以是密钥内容
|
||||
$gateway->setAlipayPublicKey($this->config['public_key']); // 可以是路径,也可以是密钥内容
|
||||
try {
|
||||
if ($gateway->verify($params)) {
|
||||
/**
|
||||
* Payment is successful
|
||||
*/
|
||||
return [
|
||||
'trade_no' => $params['out_trade_no'],
|
||||
'callback_no' => $params['trade_no']
|
||||
];
|
||||
} else {
|
||||
/**
|
||||
* Payment is not successful
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
/**
|
||||
* Payment is not successful
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
<?php
|
||||
|
||||
namespace App\Payments;
|
||||
|
||||
|
||||
class BTCPay {
|
||||
public function __construct($config) {
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
public function form()
|
||||
{
|
||||
return [
|
||||
'btcpay_url' => [
|
||||
'label' => 'API接口所在网址(包含最后的斜杠)',
|
||||
'description' => '',
|
||||
'type' => 'input',
|
||||
],
|
||||
'btcpay_storeId' => [
|
||||
'label' => 'storeId',
|
||||
'description' => '',
|
||||
'type' => 'input',
|
||||
],
|
||||
'btcpay_api_key' => [
|
||||
'label' => 'API KEY',
|
||||
'description' => '个人设置中的API KEY(非商店设置中的)',
|
||||
'type' => 'input',
|
||||
],
|
||||
'btcpay_webhook_key' => [
|
||||
'label' => 'WEBHOOK KEY',
|
||||
'description' => '',
|
||||
'type' => 'input',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function pay($order) {
|
||||
|
||||
$params = [
|
||||
'jsonResponse' => true,
|
||||
'amount' => sprintf('%.2f', $order['total_amount'] / 100),
|
||||
'currency' => 'CNY',
|
||||
'metadata' => [
|
||||
'orderId' => $order['trade_no']
|
||||
]
|
||||
];
|
||||
|
||||
$params_string = @json_encode($params);
|
||||
|
||||
$ret_raw = self::_curlPost($this->config['btcpay_url'] . 'api/v1/stores/' . $this->config['btcpay_storeId'] . '/invoices', $params_string);
|
||||
|
||||
$ret = @json_decode($ret_raw, true);
|
||||
|
||||
if(empty($ret['checkoutLink'])) {
|
||||
abort(500, "error!");
|
||||
}
|
||||
return [
|
||||
'type' => 1, // Redirect to url
|
||||
'data' => $ret['checkoutLink'],
|
||||
];
|
||||
}
|
||||
|
||||
public function notify($params) {
|
||||
$payload = trim(get_request_content());
|
||||
|
||||
$headers = getallheaders();
|
||||
|
||||
//IS Btcpay-Sig
|
||||
//NOT BTCPay-Sig
|
||||
//API doc is WRONG!
|
||||
$headerName = 'Btcpay-Sig';
|
||||
$signraturHeader = isset($headers[$headerName]) ? $headers[$headerName] : '';
|
||||
$json_param = json_decode($payload, true);
|
||||
|
||||
$computedSignature = "sha256=" . \hash_hmac('sha256', $payload, $this->config['btcpay_webhook_key']);
|
||||
|
||||
if (!self::hashEqual($signraturHeader, $computedSignature)) {
|
||||
abort(400, 'HMAC signature does not match');
|
||||
return false;
|
||||
}
|
||||
|
||||
//get order id store in metadata
|
||||
$context = stream_context_create(array(
|
||||
'http' => array(
|
||||
'method' => 'GET',
|
||||
'header' => "Authorization:" . "token " . $this->config['btcpay_api_key'] . "\r\n"
|
||||
)
|
||||
));
|
||||
|
||||
$invoiceDetail = file_get_contents($this->config['btcpay_url'] . 'api/v1/stores/' . $this->config['btcpay_storeId'] . '/invoices/' . $json_param['invoiceId'], false, $context);
|
||||
$invoiceDetail = json_decode($invoiceDetail, true);
|
||||
|
||||
|
||||
$out_trade_no = $invoiceDetail['metadata']["orderId"];
|
||||
$pay_trade_no=$json_param['invoiceId'];
|
||||
return [
|
||||
'trade_no' => $out_trade_no,
|
||||
'callback_no' => $pay_trade_no
|
||||
];
|
||||
return response('success', 200);
|
||||
|
||||
}
|
||||
|
||||
|
||||
private function _curlPost($url,$params=false){
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_HEADER, 0);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 300);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
|
||||
curl_setopt(
|
||||
$ch, CURLOPT_HTTPHEADER, array('Authorization:' .'token '.$this->config['btcpay_api_key'], 'Content-Type: application/json')
|
||||
);
|
||||
$result = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $str1
|
||||
* @param string $str2
|
||||
* @return bool
|
||||
*/
|
||||
private function hashEqual($str1, $str2)
|
||||
{
|
||||
|
||||
if (function_exists('hash_equals')) {
|
||||
return \hash_equals($str1, $str2);
|
||||
}
|
||||
|
||||
if (strlen($str1) != strlen($str2)) {
|
||||
return false;
|
||||
} else {
|
||||
$res = $str1 ^ $str2;
|
||||
$ret = 0;
|
||||
|
||||
for ($i = strlen($res) - 1; $i >= 0; $i--) {
|
||||
$ret |= ord($res[$i]);
|
||||
}
|
||||
return !$ret;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
<?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
|
||||
];
|
||||
}
|
||||
|
||||
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 ($hmac != $signHeader) { <-- Use this if you are running a version of PHP below 5.6.0 without the hash_equals function
|
||||
// abort(400, 'HMAC signature does not match');
|
||||
// }
|
||||
|
||||
if (!hash_equals($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'],
|
||||
'custom_result' => 'IPN OK'
|
||||
];
|
||||
} 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
|
||||
return('IPN OK: pending');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
<?php
|
||||
|
||||
namespace App\Payments;
|
||||
|
||||
class Coinbase {
|
||||
public function __construct($config) {
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
public function form()
|
||||
{
|
||||
return [
|
||||
'coinbase_url' => [
|
||||
'label' => '接口地址',
|
||||
'description' => '',
|
||||
'type' => 'input',
|
||||
],
|
||||
'coinbase_api_key' => [
|
||||
'label' => 'API KEY',
|
||||
'description' => '',
|
||||
'type' => 'input',
|
||||
],
|
||||
'coinbase_webhook_key' => [
|
||||
'label' => 'WEBHOOK KEY',
|
||||
'description' => '',
|
||||
'type' => 'input',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function pay($order) {
|
||||
|
||||
$params = [
|
||||
'name' => '订阅套餐',
|
||||
'description' => '订单号 ' . $order['trade_no'],
|
||||
'pricing_type' => 'fixed_price',
|
||||
'local_price' => [
|
||||
'amount' => sprintf('%.2f', $order['total_amount'] / 100),
|
||||
'currency' => 'CNY'
|
||||
],
|
||||
'metadata' => [
|
||||
"outTradeNo" => $order['trade_no'],
|
||||
],
|
||||
];
|
||||
|
||||
$params_string = http_build_query($params);
|
||||
|
||||
$ret_raw = self::_curlPost($this->config['coinbase_url'], $params_string);
|
||||
|
||||
$ret = @json_decode($ret_raw, true);
|
||||
|
||||
if(empty($ret['data']['hosted_url'])) {
|
||||
abort(500, "error!");
|
||||
}
|
||||
return [
|
||||
'type' => 1,
|
||||
'data' => $ret['data']['hosted_url'],
|
||||
];
|
||||
}
|
||||
|
||||
public function notify($params) {
|
||||
|
||||
$payload = trim(get_request_content());
|
||||
$json_param = json_decode($payload, true);
|
||||
|
||||
|
||||
$headerName = 'X-Cc-Webhook-Signature';
|
||||
$headers = getallheaders();
|
||||
$signatureHeader = isset($headers[$headerName]) ? $headers[$headerName] : '';
|
||||
$computedSignature = \hash_hmac('sha256', $payload, $this->config['coinbase_webhook_key']);
|
||||
|
||||
if (!self::hashEqual($signatureHeader, $computedSignature)) {
|
||||
abort(400, 'HMAC signature does not match');
|
||||
}
|
||||
|
||||
$out_trade_no = $json_param['event']['data']['metadata']['outTradeNo'];
|
||||
$pay_trade_no=$json_param['event']['id'];
|
||||
return [
|
||||
'trade_no' => $out_trade_no,
|
||||
'callback_no' => $pay_trade_no
|
||||
];
|
||||
return response('success', 200);
|
||||
|
||||
}
|
||||
|
||||
|
||||
private function _curlPost($url,$params=false){
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_HEADER, 0);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 300);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
|
||||
curl_setopt(
|
||||
$ch, CURLOPT_HTTPHEADER, array('X-CC-Api-Key:' .$this->config['coinbase_api_key'], 'X-CC-Version: 2018-03-22')
|
||||
);
|
||||
$result = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $str1
|
||||
* @param string $str2
|
||||
* @return bool
|
||||
*/
|
||||
public function hashEqual($str1, $str2)
|
||||
{
|
||||
if (function_exists('hash_equals')) {
|
||||
return \hash_equals($str1, $str2);
|
||||
}
|
||||
|
||||
if (strlen($str1) != strlen($str2)) {
|
||||
return false;
|
||||
} else {
|
||||
$res = $str1 ^ $str2;
|
||||
$ret = 0;
|
||||
|
||||
for ($i = strlen($res) - 1; $i >= 0; $i--) {
|
||||
$ret |= ord($res[$i]);
|
||||
}
|
||||
return !$ret;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
namespace App\Payments;
|
||||
|
||||
class EPay {
|
||||
public function __construct($config)
|
||||
{
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
public function form()
|
||||
{
|
||||
return [
|
||||
'url' => [
|
||||
'label' => 'URL',
|
||||
'description' => '',
|
||||
'type' => 'input',
|
||||
],
|
||||
'pid' => [
|
||||
'label' => 'PID',
|
||||
'description' => '',
|
||||
'type' => 'input',
|
||||
],
|
||||
'key' => [
|
||||
'label' => 'KEY',
|
||||
'description' => '',
|
||||
'type' => 'input',
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function pay($order)
|
||||
{
|
||||
$params = [
|
||||
'money' => $order['total_amount'] / 100,
|
||||
'name' => $order['trade_no'],
|
||||
'notify_url' => $order['notify_url'],
|
||||
'return_url' => $order['return_url'],
|
||||
'out_trade_no' => $order['trade_no'],
|
||||
'pid' => $this->config['pid']
|
||||
];
|
||||
ksort($params);
|
||||
reset($params);
|
||||
$str = stripslashes(urldecode(http_build_query($params))) . $this->config['key'];
|
||||
$params['sign'] = md5($str);
|
||||
$params['sign_type'] = 'MD5';
|
||||
return [
|
||||
'type' => 1, // 0:qrcode 1:url
|
||||
'data' => $this->config['url'] . '/submit.php?' . http_build_query($params)
|
||||
];
|
||||
}
|
||||
|
||||
public function notify($params)
|
||||
{
|
||||
$sign = $params['sign'];
|
||||
unset($params['sign']);
|
||||
unset($params['sign_type']);
|
||||
ksort($params);
|
||||
reset($params);
|
||||
$str = stripslashes(urldecode(http_build_query($params))) . $this->config['key'];
|
||||
if ($sign !== md5($str)) {
|
||||
return false;
|
||||
}
|
||||
return [
|
||||
'trade_no' => $params['out_trade_no'],
|
||||
'callback_no' => $params['trade_no']
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* 自己写别抄,抄NMB抄
|
||||
*/
|
||||
namespace App\Payments;
|
||||
|
||||
use \Curl\Curl;
|
||||
|
||||
class MGate {
|
||||
private $config;
|
||||
|
||||
public function __construct($config)
|
||||
{
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
public function form()
|
||||
{
|
||||
return [
|
||||
'mgate_url' => [
|
||||
'label' => 'API地址',
|
||||
'description' => '',
|
||||
'type' => 'input',
|
||||
],
|
||||
'mgate_app_id' => [
|
||||
'label' => 'APPID',
|
||||
'description' => '',
|
||||
'type' => 'input',
|
||||
],
|
||||
'mgate_app_secret' => [
|
||||
'label' => 'AppSecret',
|
||||
'description' => '',
|
||||
'type' => 'input',
|
||||
],
|
||||
'mgate_source_currency' => [
|
||||
'label' => '源货币',
|
||||
'description' => '默认CNY',
|
||||
'type' => 'input'
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function pay($order)
|
||||
{
|
||||
$params = [
|
||||
'out_trade_no' => $order['trade_no'],
|
||||
'total_amount' => $order['total_amount'],
|
||||
'notify_url' => $order['notify_url'],
|
||||
'return_url' => $order['return_url']
|
||||
];
|
||||
if (isset($this->config['mgate_source_currency'])) {
|
||||
$params['source_currency'] = $this->config['mgate_source_currency'];
|
||||
}
|
||||
$params['app_id'] = $this->config['mgate_app_id'];
|
||||
ksort($params);
|
||||
$str = http_build_query($params) . $this->config['mgate_app_secret'];
|
||||
$params['sign'] = md5($str);
|
||||
$curl = new Curl();
|
||||
$curl->setUserAgent('MGate');
|
||||
$curl->setOpt(CURLOPT_SSL_VERIFYPEER, 0);
|
||||
$curl->post($this->config['mgate_url'] . '/v1/gateway/fetch', http_build_query($params));
|
||||
$result = $curl->response;
|
||||
if (!$result) {
|
||||
abort(500, '网络异常');
|
||||
}
|
||||
if ($curl->error) {
|
||||
if (isset($result->errors)) {
|
||||
$errors = (array)$result->errors;
|
||||
abort(500, $errors[array_keys($errors)[0]][0]);
|
||||
}
|
||||
if (isset($result->message)) {
|
||||
abort(500, $result->message);
|
||||
}
|
||||
abort(500, '未知错误');
|
||||
}
|
||||
$curl->close();
|
||||
if (!isset($result->data->trade_no)) {
|
||||
abort(500, '接口请求失败');
|
||||
}
|
||||
return [
|
||||
'type' => 1, // 0:qrcode 1:url
|
||||
'data' => $result->data->pay_url
|
||||
];
|
||||
}
|
||||
|
||||
public function notify($params)
|
||||
{
|
||||
$sign = $params['sign'];
|
||||
unset($params['sign']);
|
||||
ksort($params);
|
||||
reset($params);
|
||||
$str = http_build_query($params) . $this->config['mgate_app_secret'];
|
||||
if ($sign !== md5($str)) {
|
||||
return false;
|
||||
}
|
||||
return [
|
||||
'trade_no' => $params['out_trade_no'],
|
||||
'callback_no' => $params['trade_no']
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* 自己写别抄,抄NMB抄
|
||||
*/
|
||||
namespace App\Payments;
|
||||
|
||||
use Stripe\Source;
|
||||
use Stripe\Stripe;
|
||||
|
||||
class StripeAlipay {
|
||||
public function __construct($config)
|
||||
{
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
public function form()
|
||||
{
|
||||
return [
|
||||
'currency' => [
|
||||
'label' => '货币单位',
|
||||
'description' => '',
|
||||
'type' => 'input',
|
||||
],
|
||||
'stripe_sk_live' => [
|
||||
'label' => 'SK_LIVE',
|
||||
'description' => '',
|
||||
'type' => 'input',
|
||||
],
|
||||
'stripe_webhook_key' => [
|
||||
'label' => 'WebHook密钥签名',
|
||||
'description' => '',
|
||||
'type' => 'input',
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function pay($order)
|
||||
{
|
||||
$currency = $this->config['currency'];
|
||||
$exchange = $this->exchange('CNY', strtoupper($currency));
|
||||
if (!$exchange) {
|
||||
abort(500, __('Currency conversion has timed out, please try again later'));
|
||||
}
|
||||
Stripe::setApiKey($this->config['stripe_sk_live']);
|
||||
$source = Source::create([
|
||||
'amount' => floor($order['total_amount'] * $exchange),
|
||||
'currency' => $currency,
|
||||
'type' => 'alipay',
|
||||
'statement_descriptor' => $order['trade_no'],
|
||||
'metadata' => [
|
||||
'user_id' => $order['user_id'],
|
||||
'out_trade_no' => $order['trade_no'],
|
||||
'identifier' => ''
|
||||
],
|
||||
'redirect' => [
|
||||
'return_url' => $order['return_url']
|
||||
]
|
||||
]);
|
||||
if (!$source['redirect']['url']) {
|
||||
abort(500, __('Payment gateway request failed'));
|
||||
}
|
||||
return [
|
||||
'type' => 1,
|
||||
'data' => $source['redirect']['url']
|
||||
];
|
||||
}
|
||||
|
||||
public function notify($params)
|
||||
{
|
||||
\Stripe\Stripe::setApiKey($this->config['stripe_sk_live']);
|
||||
try {
|
||||
$event = \Stripe\Webhook::constructEvent(
|
||||
get_request_content(),
|
||||
request()->header('HTTP_STRIPE_SIGNATURE'),
|
||||
$this->config['stripe_webhook_key']
|
||||
);
|
||||
} catch (\Stripe\Error\SignatureVerification $e) {
|
||||
abort(400);
|
||||
}
|
||||
switch ($event->type) {
|
||||
case 'source.chargeable':
|
||||
$object = $event->data->object;
|
||||
\Stripe\Charge::create([
|
||||
'amount' => $object->amount,
|
||||
'currency' => $object->currency,
|
||||
'source' => $object->id,
|
||||
'metadata' => json_decode($object->metadata, true)
|
||||
]);
|
||||
break;
|
||||
case 'charge.succeeded':
|
||||
$object = $event->data->object;
|
||||
if ($object->status === 'succeeded') {
|
||||
if (!isset($object->metadata->out_trade_no) && !isset($object->source->metadata)) {
|
||||
return('order error');
|
||||
}
|
||||
$metaData = isset($object->metadata->out_trade_no) ? $object->metadata : $object->source->metadata;
|
||||
$tradeNo = $metaData->out_trade_no;
|
||||
return [
|
||||
'trade_no' => $tradeNo,
|
||||
'callback_no' => $object->id
|
||||
];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
abort(500, 'event is not support');
|
||||
}
|
||||
return('success');
|
||||
}
|
||||
|
||||
private function exchange($from, $to)
|
||||
{
|
||||
$result = file_get_contents('https://api.exchangerate.host/latest?symbols=' . $to . '&base=' . $from);
|
||||
$result = json_decode($result, true);
|
||||
return $result['rates'][$to];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
<?php
|
||||
|
||||
namespace App\Payments;
|
||||
|
||||
use Stripe\Stripe;
|
||||
use Stripe\Checkout\Session;
|
||||
|
||||
class StripeCheckout {
|
||||
public function __construct($config)
|
||||
{
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
public function form()
|
||||
{
|
||||
return [
|
||||
'currency' => [
|
||||
'label' => '货币单位',
|
||||
'description' => '',
|
||||
'type' => 'input',
|
||||
],
|
||||
'stripe_sk_live' => [
|
||||
'label' => 'SK_LIVE',
|
||||
'description' => 'API 密钥',
|
||||
'type' => 'input',
|
||||
],
|
||||
'stripe_pk_live' => [
|
||||
'label' => 'PK_LIVE',
|
||||
'description' => 'API 公钥',
|
||||
'type' => 'input',
|
||||
],
|
||||
'stripe_webhook_key' => [
|
||||
'label' => 'WebHook 密钥签名',
|
||||
'description' => '',
|
||||
'type' => 'input',
|
||||
],
|
||||
'stripe_custom_field_name' => [
|
||||
'label' => '自定义字段名称',
|
||||
'description' => '例如可设置为“联系方式”,以便及时与客户取得联系',
|
||||
'type' => 'input',
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function pay($order)
|
||||
{
|
||||
$currency = $this->config['currency'];
|
||||
$exchange = $this->exchange('CNY', strtoupper($currency));
|
||||
if (!$exchange) {
|
||||
abort(500, __('Currency conversion has timed out, please try again later'));
|
||||
}
|
||||
$customFieldName = isset($this->config['stripe_custom_field_name']) ? $this->config['stripe_custom_field_name'] : 'Contact Infomation';
|
||||
|
||||
$params = [
|
||||
'success_url' => $order['return_url'],
|
||||
'cancel_url' => $order['return_url'],
|
||||
'client_reference_id' => $order['trade_no'],
|
||||
'line_items' => [
|
||||
[
|
||||
'price_data' => [
|
||||
'currency' => $currency,
|
||||
'product_data' => [
|
||||
'name' => $order['trade_no']
|
||||
],
|
||||
'unit_amount' => floor($order['total_amount'] * $exchange)
|
||||
],
|
||||
'quantity' => 1
|
||||
]
|
||||
],
|
||||
'mode' => 'payment',
|
||||
'invoice_creation' => ['enabled' => true],
|
||||
'phone_number_collection' => ['enabled' => true],
|
||||
'custom_fields' => [
|
||||
[
|
||||
'key' => 'contactinfo',
|
||||
'label' => ['type' => 'custom', 'custom' => $customFieldName],
|
||||
'type' => 'text',
|
||||
],
|
||||
],
|
||||
// 'customer_email' => $user['email'] not support
|
||||
|
||||
];
|
||||
|
||||
Stripe::setApiKey($this->config['stripe_sk_live']);
|
||||
try {
|
||||
$session = Session::create($params);
|
||||
} catch (\Exception $e) {
|
||||
info($e);
|
||||
abort(500, "Failed to create order. Error: {$e->getMessage}");
|
||||
}
|
||||
return [
|
||||
'type' => 1, // 0:qrcode 1:url
|
||||
'data' => $session->url
|
||||
];
|
||||
}
|
||||
|
||||
public function notify($params)
|
||||
{
|
||||
\Stripe\Stripe::setApiKey($this->config['stripe_sk_live']);
|
||||
try {
|
||||
$event = \Stripe\Webhook::constructEvent(
|
||||
get_request_content(),
|
||||
request()->header('HTTP_STRIPE_SIGNATURE'),
|
||||
$this->config['stripe_webhook_key']
|
||||
);
|
||||
} catch (\Stripe\Error\SignatureVerification $e) {
|
||||
abort(400);
|
||||
}
|
||||
|
||||
switch ($event->type) {
|
||||
case 'checkout.session.completed':
|
||||
$object = $event->data->object;
|
||||
if ($object->payment_status === 'paid') {
|
||||
return [
|
||||
'trade_no' => $object->client_reference_id,
|
||||
'callback_no' => $object->payment_intent
|
||||
];
|
||||
}
|
||||
break;
|
||||
case 'checkout.session.async_payment_succeeded':
|
||||
$object = $event->data->object;
|
||||
return [
|
||||
'trade_no' => $object->client_reference_id,
|
||||
'callback_no' => $object->payment_intent
|
||||
];
|
||||
break;
|
||||
default:
|
||||
abort(500, 'event is not support');
|
||||
}
|
||||
return('success');
|
||||
}
|
||||
|
||||
private function exchange($from, $to)
|
||||
{
|
||||
$result = file_get_contents('https://api.exchangerate.host/latest?symbols=' . $to . '&base=' . $from);
|
||||
$result = json_decode($result, true);
|
||||
return $result['rates'][$to];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* 自己写别抄,抄NMB抄
|
||||
*/
|
||||
namespace App\Payments;
|
||||
|
||||
use Stripe\Source;
|
||||
use Stripe\Stripe;
|
||||
|
||||
class StripeCredit {
|
||||
public function __construct($config)
|
||||
{
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
public function form()
|
||||
{
|
||||
return [
|
||||
'currency' => [
|
||||
'label' => '货币单位',
|
||||
'description' => '',
|
||||
'type' => 'input',
|
||||
],
|
||||
'stripe_sk_live' => [
|
||||
'label' => 'SK_LIVE',
|
||||
'description' => '',
|
||||
'type' => 'input',
|
||||
],
|
||||
'stripe_pk_live' => [
|
||||
'label' => 'PK_LIVE',
|
||||
'description' => '',
|
||||
'type' => 'input',
|
||||
],
|
||||
'stripe_webhook_key' => [
|
||||
'label' => 'WebHook密钥签名',
|
||||
'description' => '',
|
||||
'type' => 'input',
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function pay($order)
|
||||
{
|
||||
info($order);
|
||||
$currency = $this->config['currency'];
|
||||
$exchange = $this->exchange('CNY', strtoupper($currency));
|
||||
if (!$exchange) {
|
||||
abort(500, __('Currency conversion has timed out, please try again later'));
|
||||
}
|
||||
Stripe::setApiKey($this->config['stripe_sk_live']);
|
||||
try {
|
||||
$charge = \Stripe\Charge::create([
|
||||
'amount' => floor($order['total_amount'] * $exchange),
|
||||
'currency' => $currency,
|
||||
'source' => $order['stripe_token'],
|
||||
'metadata' => [
|
||||
'user_id' => $order['user_id'],
|
||||
'out_trade_no' => $order['trade_no'],
|
||||
'identifier' => ''
|
||||
]
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
info($e);
|
||||
abort(500, __('Payment failed. Please check your credit card information'));
|
||||
}
|
||||
if (!$charge->paid) {
|
||||
abort(500, __('Payment failed. Please check your credit card information'));
|
||||
}
|
||||
return [
|
||||
'type' => 2,
|
||||
'data' => $charge->paid
|
||||
];
|
||||
}
|
||||
|
||||
public function notify($params)
|
||||
{
|
||||
\Stripe\Stripe::setApiKey($this->config['stripe_sk_live']);
|
||||
try {
|
||||
$event = \Stripe\Webhook::constructEvent(
|
||||
get_request_content(),
|
||||
request()->header('HTTP_STRIPE_SIGNATURE'),
|
||||
$this->config['stripe_webhook_key']
|
||||
);
|
||||
} catch (\Stripe\Error\SignatureVerification $e) {
|
||||
abort(400);
|
||||
}
|
||||
switch ($event->type) {
|
||||
case 'source.chargeable':
|
||||
$object = $event->data->object;
|
||||
\Stripe\Charge::create([
|
||||
'amount' => $object->amount,
|
||||
'currency' => $object->currency,
|
||||
'source' => $object->id,
|
||||
'metadata' => json_decode($object->metadata, true)
|
||||
]);
|
||||
break;
|
||||
case 'charge.succeeded':
|
||||
$object = $event->data->object;
|
||||
if ($object->status === 'succeeded') {
|
||||
if (!isset($object->metadata->out_trade_no) && !isset($object->source->metadata)) {
|
||||
return('order error');
|
||||
}
|
||||
$metaData = isset($object->metadata->out_trade_no) ? $object->metadata : $object->source->metadata;
|
||||
$tradeNo = $metaData->out_trade_no;
|
||||
return [
|
||||
'trade_no' => $tradeNo,
|
||||
'callback_no' => $object->id
|
||||
];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
abort(500, 'event is not support');
|
||||
}
|
||||
return('success');
|
||||
}
|
||||
|
||||
private function exchange($from, $to)
|
||||
{
|
||||
$result = file_get_contents('https://api.exchangerate.host/latest?symbols=' . $to . '&base=' . $from);
|
||||
$result = json_decode($result, true);
|
||||
return $result['rates'][$to];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* 自己写别抄,抄NMB抄
|
||||
*/
|
||||
namespace App\Payments;
|
||||
|
||||
use Stripe\Source;
|
||||
use Stripe\Stripe;
|
||||
|
||||
class StripeWepay {
|
||||
public function __construct($config)
|
||||
{
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
public function form()
|
||||
{
|
||||
return [
|
||||
'currency' => [
|
||||
'label' => '货币单位',
|
||||
'description' => '',
|
||||
'type' => 'input',
|
||||
],
|
||||
'stripe_sk_live' => [
|
||||
'label' => 'SK_LIVE',
|
||||
'description' => '',
|
||||
'type' => 'input',
|
||||
],
|
||||
'stripe_webhook_key' => [
|
||||
'label' => 'WebHook密钥签名',
|
||||
'description' => '',
|
||||
'type' => 'input',
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function pay($order)
|
||||
{
|
||||
$currency = $this->config['currency'];
|
||||
$exchange = $this->exchange('CNY', strtoupper($currency));
|
||||
if (!$exchange) {
|
||||
abort(500, __('Currency conversion has timed out, please try again later'));
|
||||
}
|
||||
Stripe::setApiKey($this->config['stripe_sk_live']);
|
||||
$source = Source::create([
|
||||
'amount' => floor($order['total_amount'] * $exchange),
|
||||
'currency' => $currency,
|
||||
'type' => 'wechat',
|
||||
'statement_descriptor' => $order['trade_no'],
|
||||
'metadata' => [
|
||||
'user_id' => $order['user_id'],
|
||||
'out_trade_no' => $order['trade_no'],
|
||||
'identifier' => ''
|
||||
],
|
||||
'redirect' => [
|
||||
'return_url' => $order['return_url']
|
||||
]
|
||||
]);
|
||||
if (!$source['wechat']['qr_code_url']) {
|
||||
abort(500, __('Payment gateway request failed'));
|
||||
}
|
||||
return [
|
||||
'type' => 0,
|
||||
'data' => $source['wechat']['qr_code_url']
|
||||
];
|
||||
}
|
||||
|
||||
public function notify($params)
|
||||
{
|
||||
\Stripe\Stripe::setApiKey($this->config['stripe_sk_live']);
|
||||
try {
|
||||
$event = \Stripe\Webhook::constructEvent(
|
||||
get_request_content(),
|
||||
request()->header('HTTP_STRIPE_SIGNATURE'),
|
||||
$this->config['stripe_webhook_key']
|
||||
);
|
||||
} catch (\Stripe\Error\SignatureVerification $e) {
|
||||
abort(400);
|
||||
}
|
||||
switch ($event->type) {
|
||||
case 'source.chargeable':
|
||||
$object = $event->data->object;
|
||||
\Stripe\Charge::create([
|
||||
'amount' => $object->amount,
|
||||
'currency' => $object->currency,
|
||||
'source' => $object->id,
|
||||
'metadata' => json_decode($object->metadata, true)
|
||||
]);
|
||||
break;
|
||||
case 'charge.succeeded':
|
||||
$object = $event->data->object;
|
||||
if ($object->status === 'succeeded') {
|
||||
if (!isset($object->metadata->out_trade_no) && !isset($object->source->metadata)) {
|
||||
return('order error');
|
||||
}
|
||||
$metaData = isset($object->metadata->out_trade_no) ? $object->metadata : $object->source->metadata;
|
||||
$tradeNo = $metaData->out_trade_no;
|
||||
return [
|
||||
'trade_no' => $tradeNo,
|
||||
'callback_no' => $object->id
|
||||
];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
abort(500, 'event is not support');
|
||||
}
|
||||
return('success');
|
||||
}
|
||||
|
||||
private function exchange($from, $to)
|
||||
{
|
||||
$result = file_get_contents('https://api.exchangerate.host/latest?symbols=' . $to . '&base=' . $from);
|
||||
$result = json_decode($result, true);
|
||||
return $result['rates'][$to];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
namespace App\Payments;
|
||||
|
||||
use Omnipay\Omnipay;
|
||||
use Omnipay\WechatPay\Helper;
|
||||
|
||||
class WechatPayNative {
|
||||
public function __construct($config)
|
||||
{
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
public function form()
|
||||
{
|
||||
return [
|
||||
'app_id' => [
|
||||
'label' => 'APPID',
|
||||
'description' => '绑定微信支付商户的APPID',
|
||||
'type' => 'input',
|
||||
],
|
||||
'mch_id' => [
|
||||
'label' => '商户号',
|
||||
'description' => '微信支付商户号',
|
||||
'type' => 'input',
|
||||
],
|
||||
'api_key' => [
|
||||
'label' => 'APIKEY(v1)',
|
||||
'description' => '',
|
||||
'type' => 'input',
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function pay($order)
|
||||
{
|
||||
$gateway = Omnipay::create('WechatPay_Native');
|
||||
$gateway->setAppId($this->config['app_id']);
|
||||
$gateway->setMchId($this->config['mch_id']);
|
||||
$gateway->setApiKey($this->config['api_key']);
|
||||
$gateway->setNotifyUrl($order['notify_url']);
|
||||
|
||||
$params = [
|
||||
'body' => $order['trade_no'],
|
||||
'out_trade_no' => $order['trade_no'],
|
||||
'total_fee' => $order['total_amount'],
|
||||
'spbill_create_ip' => '0.0.0.0',
|
||||
'fee_type' => 'CNY'
|
||||
];
|
||||
|
||||
$request = $gateway->purchase($params);
|
||||
$response = $request->send();
|
||||
$response = $response->getData();
|
||||
if ($response['return_code'] !== 'SUCCESS') {
|
||||
abort(500, $response['return_msg']);
|
||||
}
|
||||
return [
|
||||
'type' => 0,
|
||||
'data' => $response['code_url'],
|
||||
'custom_result' => '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>'
|
||||
];
|
||||
}
|
||||
|
||||
public function notify($params)
|
||||
{
|
||||
$data = Helper::xml2array(get_request_content());
|
||||
$gateway = Omnipay::create('WechatPay');
|
||||
$gateway->setAppId($this->config['app_id']);
|
||||
$gateway->setMchId($this->config['mch_id']);
|
||||
$gateway->setApiKey($this->config['api_key']);
|
||||
$response = $gateway->completePurchase([
|
||||
'request_params' => get_request_content()
|
||||
])->send();
|
||||
|
||||
if (!$response->isPaid()) {
|
||||
return('FAIL');
|
||||
}
|
||||
|
||||
return [
|
||||
'trade_no' => $data['out_trade_no'],
|
||||
'callback_no' => $data['transaction_id']
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user