记录之用。
1.移动App中想要接入PayPal支付,婉转的采用PayPal的一种最简便的方式(网页版)。
border="0" name="submit" alt=" PayPal - The safer, easier way to pay online">
这方式就是支付的时候体验不太好,容易500的错误,网络的限制。
2.支付完成后那就是回调了(这里使用的PayPal的IPN回调机制):/**
* PayPal回调通知
*/
public function paypal()
{
$ipn = file_get_contents('php://input');
// $ipn = "mc_gross=399.00&protection_eligibility=Eligible&address_status=confirmed&payer_id=XEMQ4LGLL3E8U&address_street=%BF%C6%D4%B0%C2%B72%BA%C5A8%D2%F4%C0%D6%B4%F3%CF%C3&payment_date=19%3A18%3A52+Apr+07%2C+2017+PDT&payment_status=Completed&charset=gb2312&address_zip=518000&first_name=li&mc_fee=15.86&address_country_code=CN&address_name=%C9%EE%DB%DA%CA%D0%A1%A1%CA%A5%C2%EB%BF%C6%BC%BC¬ify_version=3.8&custom=664&payer_status=verified&business=yu.yu-facilitator%40zmartec.com&address_country=China&address_city=%C9%EE%DB%DA%CA%D0&quantity=1&verify_sign=AomRS5l2W2xlt2An.GaSrAzpCl-NAi.rf7W.QGkzsUIdF5RMnpDPvDzw&payer_email=zmartec%40zmartec.com&txn_id=32U88448K71697337&payment_type=instant&last_name=tao&address_state=GUANGDONG&receiver_email=yu.yu-facilitator%40zmartec.com&payment_fee=15.86&receiver_id=PEAD5Y5KWXRJU&txn_type=web_accept&item_name=SIGMA%2BSD1000&mc_currency=USD&item_number=&residence_country=US&test_ipn=1&transaction_subject=&payment_gross=399.00&ipn_track_id=b2b22318a3e9";
vendor('PaypalIPN.PaypalIPN') or die("方案7引入失败");
$pipn = new \PaypalIPN();
$ipn_response = $pipn->verifyIPN($ipn);
// 验证通过&转换数据类型为array
if (true === $ipn_response) {
$raw_post_array = explode('&', $ipn);
$myPost = array();
foreach ($raw_post_array as $keyval) {
$keyval = explode('=', $keyval);
if (count($keyval) == 2) {
// 转换urlencode的+为%2B
if ($keyval[0] === 'payment_date') {
if (substr_count($keyval[1], '+') === 1) {
$keyval[1] = str_replace('+', '%2B', $keyval[1]);
}
}
$myPost[$keyval[0]] = urldecode($keyval[1]);
}
}
$fields = "od.`uid`,od.`currency`,od.`product_id`";
$order_detail = $this->_model->orderDetail($myPost['custom'], $fields);
// 卡号iccid
$iccid = $this->_model->getIccidByid($order_detail[0]['uid']);print_r($iccid);
$iccid = $iccid[0]['iccid'];
// 套餐包id
$product_id = $this->_model->getProductIdById($order_detail[0]['product_id']);
$product_id = $product_id[0]['product_id'];
// ①检查payment_status状态
if ("Completed" == $myPost['payment_status']) {
// ②确保txn_id不重复
if ($this->_model->checkPayPalTxn($myPost['txn_id'])) {
// ③确保邮件未被更改
if ($this->paypayl_receiver_email == $myPost['receiver_email']) {
// ④确保价格、商品与订单符合
if ($order_detail[0]['order_total'] == $myPost['mc_gross'] && $order_detail[0]['currency'] == $myPost['mc_currency']) {
$data = array(
'status'=>'completed',
'payment_methods' => 'PayPal',
'trade_no'=>$myPost['txn_id'],
'changed_time'=>time()
);
$pay_result = $this->_model->saveOrderData( $data , $myPost['custom'] );
$this->hong_cha_package_order($order_detail[0]['out_trade_no'], $myPost['custom'], $product_id, $iccid, $order_detail[0]['product_amount']);
} else {
echo "货币、价格与订单不符,请联系管理员.";
}
} else {
echo "订单信息被修改,请联系管理员.";
}
} else {
echo "订单已被处理,请勿重复.";
}
} else {
echo "订单未支付完成.";
}
} else {
echo "数据被黑,无法验证通过.";
}
}
3.支付、回调之后就不可避免的要退款了:/**
* PayPal退款
*/
public function paypal_refund()
{
$txn_id = I('txn_id');
$id = I('id');
if ($this->is_data_valid(array($txn_id))) {
$url = "https://api.sandbox.paypal.com/v1/payments/sale/$txn_id/refund";
$post_data = "{}";
$access_token = $this->ger_access_token();
$header = array(
"Content-Type: application/json",
"Authorization: Bearer $access_token"
);
$output = http_post_paypal($url, $post_data, $header);
if (false === $output || false === $access_token) {
$this->_data['data'] = '';
$this->_data['error'] = true;
$this->_data['message'] = '网络异常,请您稍后重试';
}
$output = json_decode($output, TRUE);
if ($txn_id == $output['sale_id'] && "completed" == $output['completed']) {
$this->_model->saveOrderData( array('status'=>'refund_success', 'changed_time'=>time()), $id );
$this->_data['data'] = '';
$this->_data['error'] = false;
$this->_data['message'] = '退款已提交';
} elseif ("TRANSACTION_REFUSED" == $output['name']) {
$this->_data['data'] = '';
$this->_data['error'] = false;
$this->_data['message'] = '退款已提交,请勿重复';
}
}
$this->response($this->_data, 'json');
}
function.php文件:/**
* curl POST请求 用作PayPal回调
* @param string $url
* @param string $post_data
* @return array
*/
function http_post_paypal($url, $post_data, $header=array(), $client_id='', $secret='') {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
if ($client_id && $secret) {
curl_setopt($ch, CURLOPT_USERPWD, "[$client_id]:[$secret]"); // 传递一个连接中需要的用户名和密码,格式为:"[username]:[password]"。
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true) ; // 获取数据返回
curl_setopt($ch, CURLOPT_HTTPHEADER, $header) ; // 在启用 CURLOPT_RETURNTRANSFER 时候将获取数据返回array('Expect:')
$output = curl_exec($ch);
if ( curl_errno($ch) ){
return false;
}
return $output;
}
ps:退款的时候需要获取token,有碰到问题的可以参考另一篇文章http://tengteng412.blog.51cto.com/4751263/1917336