
<?php
/**
*
* @introduction 比特币支付
* @file BtcPay.class.php
* @author LegendU from KanshijianTeam
* @link http://www.kanshijian.com
*/
namespace Org\Pay;
class BtcPay{
const API='https://api.btcchina.com/api.php/payment'; //支付网关
const NOTIFYURL ='http://www.xxx.com/notify.html';
const CALLBACKURL ='http://www.xxx.com/callback.html';
const ACCESSKEY=''; //
const SECRETKEY='';
/*其他参数*/
public function __construct(){
/*其他参数初始化*/
}
/**
* 商户自己创建订单
* @author LegendU from KanshijianTeam
* 2014-12-19 下午2:33:14
*/
public function order(){
/**
* 创建订单流程
*/
$order_id='ORDER_ID'; //订单号
/**************************提交支付平台下单**************************/
//$param['price']=''; //商品的价格
//$param['currency']='CNY'; //货币种类
//$param['notificationURL']=self::NOTIFYURL; //https安全模式
//$param['returnURL']=self::CALLBACKURL;
//$param['externalKey']=$order_id; //商家用来识别此购物订单的外部密钥. 必须是唯一的. 本站订单号
//$param['itemDesc']=''; //订单描述
//$param['phoneNumber']=''; //客户手机号
//$param['settlementType']=0;
/*API 手册上的要求,但时间是下面的,不知道为啥*/
$params=array('商品价格',"CNY",self::NOTIFYURL,self::CALLBACKURL,$order_id,'商品描述','手机号',0);
/**************************请求参数 Start**************************/
try {
$json=$this->request('createPurchaseOrder', $params);
$data=json_decode($json);
$btcid=$data->result->id; //下单后支付平台返回的支付id
$url=$data->result->url; //支付地址
/*根据业务逻辑处理信息*/
} catch (\Exception $e) {
//记录日志
}
}
/**
* 异步通知
* @author LegendU from KanshijianTeam
* 2014-12-19 下午2:41:29
*/
public function notify(){
$head=$_SERVER['HTTP_X_BTCCHINA_SIGNATURE'];
$json = isset($GLOBALS["HTTP_RAW_POST_DATA"])?$GLOBALS["HTTP_RAW_POST_DATA"]:'';
/*验证合法性*/
if ($head==sha1($json.self::SECRETKEY)){
$data=json_decode($json);
$data=(array)$data;
if ($data['status']=='paid'){
/*根据业务逻辑处理信息*/
/*查询订单,并修改订单状态*/
}else{
/*根据业务逻辑处理信息*/
}
echo 'success';
}else{
echo 'fail';
//记录日志
}
}
/**
* 同步通知
* @author LegendU from KanshijianTeam
* 2014-12-19 下午2:44:05
*/
public function callback(){
$btcid=I('purchaseorder_id',0,'intval');
$json=$this->request('getPurchaseOrder',array($btcid)); //注意,这里传递是数组
$data=json_decode($json);
$data=(array)$data;
if ($data['status']=='paid'){
/*根据业务逻辑处理信息*/
/*判断订单是否根据notify已经修改订单状态,若没有,根据getPurchaseOrder修改订单状态*/
}else{
/*根据业务逻辑处理信息*/
}
}
private function sign($method, $params = array()){
$mt = explode(' ', microtime());
$ts = $mt[1] . substr($mt[0], 2, 6);
$signature = urldecode(http_build_query(array(
'tonce' => $ts,
'accesskey' => self::ACCESSKEY,
'requestmethod' => 'post',
'id' => 1,
'method' => $method,
'params' => implode(',', $params),
)));
$hash = hash_hmac('sha1', $signature, self::ACCESSKEY);
return array(
'ts' => $ts,
'hash' => $hash,
'auth' => base64_encode(self::ACCESSKEY.':'. $hash),
);
}
private function request($method, $params){
$sign = $this->sign($method, $params);
$options = array(
CURLOPT_HTTPHEADER => array(
'Authorization: Basic ' . $sign['auth'],
'Json-Rpc-Tonce: ' . $sign['ts'],
),
);
$postData = json_encode(array(
'method' => $method,
'params' => $params,
'id' => 1,
));
$headers = array(
'Authorization: Basic ' . $sign['auth'],
'Json-Rpc-Tonce: ' . $sign['ts'],
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERAGENT,'Mozilla/4.0 (compatible; BTC China Trade Bot; '.php_uname('a').'; PHP/'.phpversion().')');
curl_setopt($ch, CURLOPT_URL, 'https://api.btcchina.com/api.php/payment');
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
$res = curl_exec($ch);
return $res;
}
}