需求
老板:咱们公司想打欧美市场,在线支付这一块再用支付宝和微信就不合适了,你找一个比较适合国外人的支付方式,把他们的钱装进咱们公司的口袋里;
经过深思熟虑和多出调研;paypal是最适合国际市场的一种支付方式
概述
paypal官网:https://www.paypal.com/
PayPal是eBay旗下的一家公司,致力于让个人或企业通过电子邮件,安全、简单、便捷地实现在线付款和收款。PayPal账户是PayPal公司推出的最安全的网络电子账户,使用它可有效降低网络欺诈的发生。PayPal账户所集成的高级管理功能,使您能轻松掌控每一笔交易详情。截止2017年,在跨国交易中超过90%的卖家和超过85%的买家认可并正在使用PayPal电子支付业务。全球用户广 ,PayPal在全球190国家和地区;实时交易,即时到账;支持美元、欧元、英镑等20多种货币付款;安全保障高,使用成本低。
实现方式
本文以语言PHP,框架laravel为例 srmklive/paypal插件
1.使用composer命令安装:
composer require srmklive/paypal
2. 将服务提供程序添加到文件中的$providers数组,config/app.php下
Srmklive \ PayPal \ Providers \ PayPalServiceProvider :: class
将别名添加到文件中的$aliases数组,config/app.php:
' PayPal ' => Srmklive \ PayPal \ Facades \ PayPal :: class
3. 运行php artisan命令生成config配置文件:
php artisan vendor:publish --provider "Srmklive\PayPal\Providers\PayPalServiceProvider"
config/paypal.php 文件内容
return [
'mode' => 'live',//只能是'sandbox'或'live'。如果为空或无效,将使用“live”。
'sandbox' => [
'username' => env('PAYPAL_SANDBOX_API_USERNAME', ''),
'password' => env('PAYPAL_SANDBOX_API_PASSWORD', ''),
'secret' => env('PAYPAL_SANDBOX_API_SECRET', ''),
'certificate' => env('PAYPAL_SANDBOX_API_CERTIFICATE', ''),
'app_id' => 'APP-80W284485P519543T',//用于测试沙盒模式下的自适应支付API
],
'live' => [
'username' => env('PAYPAL_LIVE_API_USERNAME', ''),
'password' => env('PAYPAL_LIVE_API_PASSWORD', ''),
'secret' => env('PAYPAL_LIVE_API_SECRET', ''),
'certificate' => env('PAYPAL_LIVE_API_CERTIFICATE', ''),
'app_id' => '',//用于自适应付款API
],
'payment_action' => 'Sale', // 只能为 'Sale', 'Authorization' ,'Order'
'currency' => 'TWD', //默认币种 台湾币
'billing_type' => '', //如果仅仅使用及时支付,这里为空
'notify_url' => '', // Change this accordingly for your application.
'locale' => '', //强制网关语言即it_IT,es_ES,en_US ...(仅限快速结账)
'validate_ssl' => true,//创建api客户端时验证SSL
];
将此添加到.env.example和.env
#沙盒环境
PAYPAL_SANDBOX_API_USERNAME=
PAYPAL_SANDBOX_API_PASSWORD=
PAYPAL_SANDBOX_API_SECRET=
PAYPAL_SANDBOX_API_CERTIFICATE=
#真实环境
PAYPAL_LIVE_API_USERNAME=
PAYPAL_LIVE_API_PASSWORD=
PAYPAL_LIVE_API_SECRET=
PAYPAL_LIVE_API_CERTIFICATE=
订单支付逻辑代码
获取订单数据
订单单个商品金额*商品个数+其他商品金额一定要等于总金额
public function getCart()
{
$data = [];
$data['items'] = [
[
'name' => 'Product 1',//商品名称
'price' => 9.99, //商品价格
'qty' => 1 //商品个数
],
[
'name' => 'Product 2',//商品名称
'price' => 4.99, //商品价格
'qty' => 2 //商品个数
]
];
$data['invoice_id'] = 1; //订单id
$data['invoice_description'] = "Order #{$data['invoice_id']} Invoice";//订单描述
$data['return_url'] = url('/expressCheckoutSuccess');//统一下单成功,跳转地址
$data['cancel_url'] = url('/paypal_send?order_id='.$data['invoice_id'].);//下单失败,跳转地址
$total = 0;
foreach($data['items'] as $item) {
$total += $item['price']*$item['qty'];
}
$data['total'] = $total;//订单总额
return $data;
}
paypal下单
如果在下单时,如果在setExpressCheckout方法前设置支付币种,一定要在doExpressCheckoutPayment方法之前也设置币种,不然执行do方法会走默认币种,币种不统一,报错
$data = $this->getCart();
$this->provider->setCurrency('USD')->setExpressCheckout($data); //设置paypal支付币种(可以使用config中的默认)
$response = $provider->setExpressCheckout($data);//设置参数,获取paypal链接(及时支付)
//$response = $provider->setExpressCheckout($data, true); //在创建定期付款配置文件(订阅)时使用以下行
return redirect($response['paypal_link']);//用户重定向到PayPal的url地址
订单成功页
public function expressCheckoutSuccess(Request $request)
{
$token = $request->get('token');
$PayerID = $request->get('PayerID');//支付者paypalid
$response = $this->provider->getExpressCheckoutDetails($token);//解析回调数据
if (!in_array(strtoupper($response['ACK']), ['SUCCESS', 'SUCCESSWITHWARNING'])) {
$invoice_id = explode('_', $response['INVNUM'])[1];
try{
$order=\App\order::where('order_id',$invoice_id)->update(['order_type'=>'12']);
}catch(Exception $e){
}
return redirect('/endfail')->with(['type' =>'0']);
}
$invoice_id = explode('_', $response['INVNUM'])[1];//获取数据库订单表中订单号
$cart = $this->getCart();//获取发起请求时组装的参数
$this->provider->setCurrency('USD')->setExpressCheckout($cart);//设置币种
//二次验证回调数据
$payment_status = $this->provider->doExpressCheckoutPayment($cart, $token, $PayerID);
if (!in_array(strtoupper($payment_status['ACK']), ['SUCCESS', 'SUCCESSWITHWARNING'])) {
$invoice_id = explode('_', $response['INVNUM'])[1];
try{
$order=\App\order::where('order_id',$invoice_id)->update(['order_type'=>'12']);
}catch(Exception $e){
}
return redirect('/endfail?type=0');//订单失败
}
//处理订单数据,存储下单信息
........
return redirect("/endsuccess?type=1&goods_id={$goods_id}&order_id={$order_id}");//订单成功
}
订单失败
public function paypal_send()
{
$order_id = $_GET['order_id'];
$msg=\App\order::where('order_id',$order_id)->first()['order_type'];
$order = order::where('order_id', $order_id)->delete();
return redirect('/pay');
}
好了,今天的paypal分享就到这里了,已经基本实现paypal的及时在线支付功能,代码中getCart()方法为假数据,如果真实情况开发需要订单表提供真实数据,希望能帮到来参观的道友,加油