This repository has been archived by the owner on May 7, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 110
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
303 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
vendor | ||
.idea | ||
composer.lock | ||
public/yz.log |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
{ | ||
"name": "xu42/pay", | ||
"type": "project", | ||
"license": "MIT", | ||
"authors": [ | ||
{ | ||
"name": "xu42", | ||
"email": "xu42.cn@gmail.com" | ||
} | ||
], | ||
"autoload": { | ||
"psr-4": { | ||
"Pay\\": "src/" | ||
} | ||
}, | ||
"require": { | ||
"xu42/open-sdk": "^1.0", | ||
"workerman/workerman": "^3.5" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
<html lang="zh_CN" xmlns:v-bind="http://www.w3.org/1999/xhtml" xmlns:v-on="http://www.w3.org/1999/xhtml"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<title>在线收款 - 个人开发者的福音 - 基于有赞云</title> | ||
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=0"> | ||
<style> | ||
body{text-align:center;background-color:#e0e0e0}#app{margin:0 auto}#app h2{padding-top:3%}#intro{padding-top:2%;text-align:center}#app img{padding-top:3%;width:280px}#app input{margin:1%} | ||
</style> | ||
</head> | ||
<body> | ||
<div id="app"> | ||
<h2>在线收款Demo</h2> | ||
<div id="intro"> | ||
1. 支持支付宝、微信、信用卡,扫码付款<br> | ||
2. 无需公司资质、无需接入支付宝、微信<br> | ||
3. 基于有赞云可信赖,费率低每笔交易1%<br> | ||
</div> | ||
<img v-bind:src="qrcode"> | ||
<div id="input_price"> | ||
<input v-model="price" placeholder="输入金额(单位: 分)"> | ||
<button v-on:click="generate">点此生成支付二维码</button> | ||
</div> | ||
</div> | ||
|
||
|
||
<a href="https://github.com/xu42/pay"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://camo.githubusercontent.com/652c5b9acfaddf3a9c326fa6bde407b87f7be0f4/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f6f72616e67655f6666373630302e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_orange_ff7600.png"></a></body> | ||
|
||
|
||
<script src="//cdn.staticfile.org/vue/2.2.6/vue.min.js"></script> | ||
<script> | ||
var clientId = ''; | ||
var ws = new WebSocket('ws://127.0.0.1:11942'); | ||
var app = new Vue({ | ||
el: '#app', | ||
data: { | ||
qrcode: 'https://img.yzcdn.cn/upload_files/2017/11/25/FlaMfOlko4gdrls7LmdfHDtoACxK.jpg', | ||
price: 10 | ||
}, | ||
methods: { | ||
generate: function () { | ||
clientId = Math.random().toString(36).substr(2); | ||
ws.send(clientId + ',' + app.price); | ||
} | ||
} | ||
}); | ||
|
||
ws.onmessage = function (response) { | ||
|
||
var responseObj = JSON.parse(response.data); | ||
|
||
if (responseObj.code !== 200) { | ||
alert(responseObj.msg); | ||
return; | ||
} | ||
|
||
if (responseObj.event === 'pay') { | ||
if (responseObj.data === 'WAIT_BUYER_PAY') app.qrcode = 'https://img.yzcdn.cn/upload_files/2017/11/25/FqZjK96_t4g3PYC7m58RHXQ4PCRm.png'; | ||
if (responseObj.data === 'TRADE_SUCCESS') app.qrcode = 'https://img.yzcdn.cn/upload_files/2017/11/25/FnFa-_giR389G_rtBBWspFw8esc7.png'; | ||
} | ||
|
||
if (responseObj.event === 'create') { | ||
app.qrcode = responseObj.data.qr; | ||
} | ||
}; | ||
</script> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
<?php | ||
|
||
require_once __DIR__ . '/../src/Service/TradeService.php'; | ||
|
||
$request = $GLOBALS['HTTP_RAW_POST_DATA']; | ||
|
||
echo json_encode(['code' => 0, 'msg' => 'success']); | ||
|
||
file_put_contents('yz.log', $request . PHP_EOL, FILE_APPEND); | ||
|
||
$request = json_decode($request, true); | ||
|
||
if (empty($request) || !isset($request['kdt_id']) || !isset($request['id']) || !isset($request['status'])) { | ||
return; | ||
} | ||
|
||
|
||
$QRId = (new Service\TradeService)->getQRId($request['id']); | ||
if (empty($QRId)) return "send QRId is empty"; | ||
|
||
$client = stream_socket_client('tcp://127.0.0.1:11900'); | ||
$data = array('qrId' => $QRId, 'msg' => $request['status']); | ||
fwrite($client, json_encode($data) . "\n"); | ||
$res = fread($client, 8192); | ||
|
||
file_put_contents('yz.log', 'QRID:' . (string)$QRId . '--' . 'pushRes:' . $res . PHP_EOL, FILE_APPEND); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
<?php | ||
|
||
namespace Service; | ||
|
||
class InnerTextServer | ||
{ | ||
/** | ||
* @param \Workerman\Connection\TcpConnection $connection | ||
* @param string $message | ||
*/ | ||
public static function onMessage($connection, $message) | ||
{ | ||
$data = json_decode($message, true); | ||
$json = json_encode(['code' => 200, 'msg' => 'success', 'event' => 'pay', 'data' => $data['msg']]); | ||
$sendRes = self::sendMessageByQRId($data['qrId'], $json); | ||
$connection->send($sendRes ? 'success' : 'error'); | ||
} | ||
|
||
private static function sendMessageByQRId($QRId, $message) | ||
{ | ||
global $webSocketServer; | ||
|
||
if (!isset($webSocketServer->userQRs[$QRId])) return false; | ||
$userId = $webSocketServer->userQRs[$QRId]; | ||
|
||
if (!isset($webSocketServer->userConnections[$userId])) return false; | ||
/** @var \Workerman\Connection\TcpConnection $connection $connection */ | ||
$connection = $webSocketServer->userConnections[$userId]; | ||
return $connection->send($message); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
<?php | ||
|
||
namespace Service; | ||
|
||
use Exception; | ||
use Youzan\Open\Client; | ||
|
||
class PayService extends YouzanYunService | ||
{ | ||
|
||
/** | ||
* @param \Workerman\Connection\TcpConnection $connection | ||
* @param $price | ||
*/ | ||
public function create($connection, $price) | ||
{ | ||
global $webSocketServer; | ||
$price = abs(intval($price)) != 0 ? abs(intval($price)) : 10; | ||
|
||
try { | ||
$response = $this->createPayQRCode($this->getAccessToken(), $price); | ||
$connection->send(json_encode(['code' => 200, 'msg' => 'success', 'event' => 'create', 'data' => ['qr' => $response['qr_code']]])); | ||
$webSocketServer->userQRs[$response['qr_id']] = $connection->userId; | ||
} catch (Exception $e) { | ||
$connection->send(json_encode(['code' => 1000, 'msg' => $e->getMessage(), 'event' => 'create', 'data' => []])); | ||
} | ||
} | ||
|
||
|
||
private function createPayQRCode($accessToken, $price = 1) | ||
{ | ||
$apiVersion = $this->config['api']['version']; | ||
$createPayQRCode = $this->config['api']['createPayQRCode']; | ||
|
||
$params = [ | ||
'qr_price' => abs(intval($price)), | ||
'qr_name' => 'Demo By Xu42', | ||
'qr_type' => 'QR_TYPE_DYNAMIC', | ||
]; | ||
|
||
$response = (new Client($accessToken))->get($createPayQRCode, $apiVersion, $params); | ||
if (!isset($response['response']['qr_code'])) throw new Exception('wrong create pay qrcode'); | ||
return $response['response']; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
<?php | ||
|
||
namespace Service; | ||
|
||
require_once 'YouzanYunService.php'; | ||
|
||
use Exception; | ||
use Youzan\Open\Client; | ||
|
||
class TradeService extends YouzanYunService | ||
{ | ||
public function getQRId($orderNo) | ||
{ | ||
try { | ||
$tradeInfo = $this->getSingleTrade($orderNo); | ||
return $tradeInfo['trade']['qr_id']; | ||
} catch (Exception $e) { | ||
return 0; | ||
} | ||
} | ||
|
||
public function getSingleTrade($orderNo) | ||
{ | ||
$apiVersion = $this->config['api']['version']; | ||
$getTrade = $this->config['api']['getTrade']; | ||
|
||
$params = [ | ||
'tid' => $orderNo, | ||
'with_childs' => false, | ||
'fields' => 'qr_id' | ||
]; | ||
|
||
$response = (new Client($this->getAccessToken()))->get($getTrade, $apiVersion, $params); | ||
var_dump($response); | ||
if (!isset($response['response'])) throw new Exception('wrong getTrade'); | ||
return $response['response']; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
<?php | ||
|
||
namespace Service; | ||
|
||
use Exception; | ||
use Youzan\Open\Token; | ||
|
||
class YouzanYunService | ||
{ | ||
protected $config = []; | ||
|
||
public function __construct() | ||
{ | ||
$this->config = [ | ||
'type' => 'self', | ||
'kdtId' => '0000', | ||
'clientId' => '00000', | ||
'clientSecret' => '0000', | ||
'api' => [ | ||
'version' => '3.0.0', | ||
'getTrade' => 'youzan.trade.get', | ||
'createPayQRCode' => 'youzan.pay.qrcode.create', | ||
], | ||
]; | ||
} | ||
|
||
protected function getAccessToken() | ||
{ | ||
$clientId = $this->config['clientId']; | ||
$clientSecret = $this->config['clientSecret']; | ||
$type = $this->config['type']; | ||
$keys = [ | ||
'kdt_id' => $this->config['kdtId'] | ||
]; | ||
|
||
$accessToken = (new Token($clientId, $clientSecret))->getToken($type, $keys); | ||
if (!isset($accessToken['access_token'])) throw new Exception('wrong server pay config'); | ||
return $accessToken['access_token']; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
<?php | ||
|
||
require_once __DIR__ . '/../vendor/autoload.php'; | ||
|
||
use Service\PayService; | ||
use Workerman\WebServer; | ||
use Workerman\Worker; | ||
|
||
|
||
$webServer = new WebServer('http://127.0.0.1:8083'); | ||
$webServer->addRoot('localhost:8083', __DIR__ . '/../public/'); | ||
$webServer->count = 3; | ||
|
||
$webSocketServer = new Worker('websocket://127.0.0.1:11942'); | ||
$webSocketServer->count = 1; | ||
$webSocketServer->userConnections = []; | ||
$webSocketServer->userQRs = []; | ||
$webSocketServer->onWorkerStart = function () use ($webSocketServer) { | ||
$textWorker = new Worker('Text://127.0.0.1:11900'); | ||
$textWorker->onMessage = 'Service\\InnerTextServer::onMessage'; | ||
$textWorker->listen(); | ||
}; | ||
$webSocketServer->onMessage = function ($connection, $message) use ($webSocketServer) { | ||
$arr = explode(',', $message); | ||
if (!isset($connection->userId)) { | ||
$connection->userId = $arr[0]; | ||
$webSocketServer->userConnections[$connection->userId] = $connection; | ||
} | ||
(new PayService)->create($connection, $arr[1]); | ||
}; | ||
|
||
|
||
Worker::runAll(); |