Paypal支付,是目前网站流行的一种支付方式,Paypal也是需要依赖工具包来进行开发
paypal依赖包 composer require paypal/rest-api-sdk-php
用 composer 命令来下载依赖包
Paypal支付的参数也是要用到Paypal秘钥和ID,查看Paypal API文档,来进行开发,对接,
参考文档 https://learnku.com/articles/26282,这是参考文档,可以去翻阅查看
沙盒环境
沙盒环境就和本地环境差不多,是一种模拟Paypal的流程支付环境也称沙盒环境
沙盒登录 https://www.sandbox.paypal.com/c2/signin
参考这个文档进行调试和开发
下面是Paypal支付调取,同步回调和异步回调,退款的方法,
PayPal = new ApiContext(
new OAuthTokenCredential(
self::clientId,
self::clientSecret
)
);
//如果是沙盒测试环境不设置,请注释掉
// $this->PayPal->setConfig(
// array(
// 'mode' => 'live',
// )
// );
}
/**
* paypal支付
* @param $price float 金额
* @param $order_sn string 订单号
* @param $product string 商品名
* @param $description string 商品描述
* @param $shipping float 运费
*
*/
public function pay($price=10, $order_sn=123456, $product='商品', $description='描述内容', $shipping = 0)
{
$paypal = $this->PayPal;
$total = $price + $shipping;//总价
$payer = new Payer();
$payer->setPaymentMethod('paypal');
$item = new Item();
$item->setName($product)->setCurrency(self::Currency)->setQuantity(1)->setPrice($price);
$itemList = new ItemList();
$itemList->setItems([$item]);
$details = new Details();
$details->setShipping($shipping)->setSubtotal($price);
$amount = new Amount();
$amount->setCurrency(self::Currency)->setTotal($total)->setDetails($details);
$transaction = new Transaction();
$transaction->setAmount($amount)->setItemList($itemList)->setDescription($description)->setInvoiceNumber(uniqid());
$redirectUrls = new RedirectUrls();
$redirectUrls->setReturnUrl(self::accept_url . '?success=true&order_sn='.$order_sn)->setCancelUrl(self::accept_url . '/?success=false');
$payment = new Payment();
$payment->setIntent('sale')->setPayer($payer)->setRedirectUrls($redirectUrls)->setTransactions([$transaction]);
try {
$payment->create($paypal);
$approvalUrl = $payment->getApprovalLink();
echo json_encode(['code'=>200, 'msg'=>'成功!','url'=>$approvalUrl]);
//header("Location: {$approvalUrl}"); //自动跳转页面
exit();
} catch (PayPalConnectionException $e) {
error_log(date('Y-m-d H:i:s')." paypal pay fail: ".$e->getData()."\n", 3, self::error_log);
echo json_encode(['code'=>202, 'msg'=>$e->getData()]);
exit();
}
}
/**
* 同步回调方法
*/
public function Callback()
{
$success = trim($_GET['success']);
if ($success == 'false' && !isset($_GET['paymentId']) && !isset($_GET['PayerID'])) {
error_log(date('Y-m-d H:i:s')." paypal Callback fail: 取消付款"."\n", 3, self::error_log);
echo json_encode(['code'=>202, 'msg'=>'取消付款']);
exit();
}
$paymentId = trim($_GET['paymentId']);
$PayerID = trim($_GET['PayerID']);
$order_sn = trim($_GET['order_sn']); //订单号
if (!isset($success, $paymentId, $PayerID)) {
error_log(date('Y-m-d H:i:s')." paypal Callback fail: 支付失败"."\n", 3, self::error_log);
echo json_encode(['code'=>202, 'msg'=>'支付失败']);
exit();
}
if ((bool)$_GET['success'] === 'false') {
error_log(date('Y-m-d H:i:s')." paypal Callback fail:".'支付失败,支付ID【' . $paymentId . '】,支付人ID【' . $PayerID . '】'."\n", 3, self::error_log);
echo json_encode(['code'=>202,'msg'=>'支付失败,支付ID【' . $paymentId . '】,支付人ID【' . $PayerID . '】']);
exit();
}
$payment = Payment::get($paymentId, $this->PayPal);
$execute = new PaymentExecution();
$execute->setPayerId($PayerID);
try {
$payment->execute($execute, $this->PayPal);
// error_log(date('Y-m-d H:i:s')."同步回调:".json_encode($_GET)."\n", 3, self::error_log);
/*
* 将$paymentId保存到数据表
* */
echo json_encode(['code'=>200,'msg'=>'支付成功,支付ID【' . $paymentId . '】,支付人ID【' . $PayerID . '】,订单号【'.$order_sn.'】']);
exit();
} catch (Exception $e) {
error_log(date('Y-m-d H:i:s')." paypal Callback fail:".$e->getMessage(). ",支付失败,支付ID【" . $paymentId . "】,支付人ID【" . $PayerID . "】"."\n", 3, self::error_log);
echo json_encode(['code'=>202,'msg'=>$e . ',支付失败,支付ID【' . $paymentId . '】,支付人ID【' . $PayerID . '】']);
exit();
}
}
//异步回调(在控制台设置)
public function notify(){
//通知结果 https://developer.paypal.com/docs/api-basics/notifications/webhooks/notification-messages/
$json_data = file_get_contents('php://input');
// error_log(date('Y-m-d H:i:s')."异步回调:".$json_data."\n", 3, self::error_log);
$json_data = str_replace("'", '', $json_data);
$json_data = json_decode($json_data,true);
if(empty($json_data)){
error_log(date('Y-m-d H:i:s')."paypal notify fail: 参加为空!"."\n", 3, self::error_log);
exit();
}
try {
//自己打印$json_data的值看有那些是你业务上用到的
$id = $json_data['resource']['id']; //付款id(退款用),存表
$paymentId = $json_data['resource']['parent_payment']; //用此字段查询出订单表
if($json_data['resource_type']=='sale'){ //支付完成
/*
* 处理相关业务
* */
}elseif ($json_data['resource_type']=='refund'){ //退款成功
$total=$json_data['resource']['amount']['total']; //退款金额
/*
* 处理相关业务
* */
}
} catch (\Exception $e) {
//记录错误日志
error_log(date('Y-m-d H:i:s')."paypal notify fail:".$e->getMessage()."\n", 3, self::error_log);
exit();
}
return "success";
}
//退款
public function returnMoney($txn_id = "3LV45487XU194815F",$price=1){ //异步回调中拿到的id
try {
$amt = new Amount();
$amt->setCurrency('USD')
->setTotal($price); // 退款的费用
$refund = new Refund();
$refund->setAmount($amt);
$sale = new Sale();
$sale->setId($txn_id);
$refundedSale = $sale->refund($refund, $this->PayPal);
} catch (\Exception $e) {
// PayPal无效退款
// return json_decode(json_encode(['message' => $e->getMessage(), 'code' => $e->getCode(), 'state' => $e->getMessage()])); // to object
echo json_encode(['code' => 202,'msg'=> $e->getMessage()]);
exit();
}
$refundedSale = $refundedSale->toArray();
// 退款完成
if($refundedSale['state']=='completed'){
echo json_encode(['code' => 200,'msg' =>'退款成功!']);
exit();
}else{
echo json_encode(['code' => 202,'msg' =>'退款失败!']);
exit();
}
}
}
0条评论