步骤一:注册账号(个人账号)
https://www.paypal.com/us/home#/pattern/confirm
步骤二:创建沙箱账号,用申请的账号登录地址:
https://developer.paypal.com/developer/accounts/
获取测试登录账号和密码。
步骤三:登录沙箱账号(沙箱账号,只能在沙箱地址上登录;主账号不能在沙箱地址上登录):
https://www.sandbox.paypal.com/c2/signin?country.x=C2&locale.x=zh_C2
步骤四:获取沙箱Client ID和Secret。用主账号登录:
https://developer.paypal.com/developer/applications/
创建App:
步骤五:在我的项目安装paypal支付源码,可以直接composer安装:
composer require "paypal/rest-api-sdk-php:*"
参考官方安装地址:
https://github.com/paypal/PayPal-PHP-SDK/wiki
步骤六:创建服务端checkout,能访问:
setPaymentMethod('paypal');
$amount = new \PayPal\Api\Amount();
$amount->setTotal('1.00');
$amount->setCurrency('USD');
$transaction = new \PayPal\Api\Transaction();
$transaction->setAmount($amount);
$redirectUrls = new \PayPal\Api\RedirectUrls();
$redirectUrls->setReturnUrl("https://example.com/your_redirect_url.html")//执行付款
->setCancelUrl("https://example.com/your_cancel_url.html");//取消付款
$payment = new \PayPal\Api\Payment();
$payment->setIntent('sale')
->setPayer($payer)
->setTransactions(array($transaction))
->setRedirectUrls($redirectUrls);
// After Step 3
try {
$payment->create($apiContext);
echo $payment;
echo "\n\nRedirect user to approval_url: " . $payment->getApprovalLink() . "\n";
}
catch (\PayPal\Exception\PayPalConnectionException $ex) {
// This will print the detailed information on the exception.
//REALLY HELPFUL FOR DEBUGGING
echo $ex->getData();
}
$approvalUrl = $payment->getApprovalLink();
header("Location: {$approvalUrl}");
执行以上代码最终会跳出,期间会需要登录,就是你创建的buyer@账号:
步骤七:执行付款 注意步骤六的执行付款注释及其对应的url:
setPaymentMethod("paypal");
// ### Itemized information
// (Optional) Lets you specify item wise
// information
$item1 = new Item();
$item1->setName('Ground Coffee 40 oz')
->setCurrency('USD')
->setQuantity(1)
->setSku("123123") // Similar to `item_number` in Classic API
->setPrice(7.5);
$item2 = new Item();
$item2->setName('Granola bars')
->setCurrency('USD')
->setQuantity(5)
->setSku("321321") // Similar to `item_number` in Classic API
->setPrice(2);
$itemList = new ItemList();
$itemList->setItems(array($item1, $item2));
// ### Additional payment details
// Use this optional field to set additional
// payment information such as tax, shipping
// charges etc.
$details = new Details();
$details->setShipping(1.2)
->setTax(1.3)
->setSubtotal(17.50);
// ### Amount
// Lets you specify a payment amount.
// You can also specify additional details
// such as shipping, tax.
$amount = new Amount();
$amount->setCurrency("USD")
->setTotal(20)
->setDetails($details);
// ### Transaction
// A transaction defines the contract of a
// payment - what is the payment for and who
// is fulfilling it.
$transaction = new Transaction();
$transaction->setAmount($amount)
->setItemList($itemList)
->setDescription("Payment description")
->setInvoiceNumber(uniqid());
// ### Redirect urls
// Set the urls that the buyer must be redirected to after
// payment approval/ cancellation.
$baseUrl = getBaseUrl();
$redirectUrls = new RedirectUrls();
$redirectUrls->setReturnUrl("$baseUrl/ExecutePayment.php?success=true")
->setCancelUrl("$baseUrl/ExecutePayment.php?success=false");
// ### Payment
// A Payment Resource; create one using
// the above types and intent set to 'sale'
$payment = new Payment();
$payment->setIntent("sale")
->setPayer($payer)
->setRedirectUrls($redirectUrls)
->setTransactions(array($transaction));
// For Sample Purposes Only.
$request = clone $payment;
// ### Create Payment
// Create a payment by calling the 'create' method
// passing it a valid apiContext.
// (See bootstrap.php for more on `ApiContext`)
// The return object contains the state and the
// url to which the buyer must be redirected to
// for payment approval
try {
$payment->create($apiContext);
} catch (Exception $ex) {
// NOTE: PLEASE DO NOT USE RESULTPRINTER CLASS IN YOUR ORIGINAL CODE. FOR SAMPLE ONLY
ResultPrinter::printError("Created Payment Using PayPal. Please visit the URL to Approve.", "Payment", null, $request, $ex);
exit(1);
}
// ### Get redirect url
// The API response provides the url that you must redirect
// the buyer to. Retrieve the url from the $payment->getApprovalLink()
// method
$approvalUrl = $payment->getApprovalLink();
// NOTE: PLEASE DO NOT USE RESULTPRINTER CLASS IN YOUR ORIGINAL CODE. FOR SAMPLE ONLY
ResultPrinter::printResult("Created Payment Using PayPal. Please visit the URL to Approve.", "Payment", "$approvalUrl", $request, $payment);
return $payment;
步骤八:配置回调数据验证notify,登录主账号:
注意:必须使用https,否则创建失败。
步骤九:验证数据:
verifyNotify($content);
if ($verify) {
return true;
}else{
return false;
}
}else{
return false;
}
function verifyNotify($post)
{
if(empty($post)){
return false;
}
$post = json_decode($post, true);
/**
* completed 表示订单状态ok. 这里怕是伪造的数据。去paypal服务器上去查
*/
if ($post['resource']['state'] != 'completed') {
return false;
}
/**
* invoice_number,【在客户端(ios或安卓)】发起支付的时候加入进去的。如果这个数据是空的,客户端配置有问题。
* 【客户端请求服务器,自己生成的唯一订单号,给客户端,客户端再加入到palpal支付参数里边】
* 收取订单号
*/
$saleId = $post['resource']['sale_id'] ?: $post['resource']['id'];
//查询订单
$apiContext = $this->getApiContext();
try{
$sale = Sale::get($saleId, $apiContext);
$orderId = $sale->invoice_number;//$post['resource']['invoice_number'] 订单号
$st = $sale->getState();
if($st == 'completed'){
//付款类型COMPLETED
//验证成功之后的逻辑。
return true;
} elseif($st == 'reversed'){
//REVERSED PayPal reverses a sale
//更新数据 用户申请退款,paypal官方介入
}else{
return false;
}
}catch (\Exception $ex){
//抛出异常。
return false;
}
}
Tips:
Paypal安装教程:
https://github.com/paypal/PayPal-PHP-SDK/wiki
REST API Samples 地址:
http://paypal.github.io/PayPal-PHP-SDK/sample/
销售状态码:
https://developer.paypal.com/docs/integration/direct/webhooks/event-names/#sales
paypal开发者文档(这里使用的checkout文档):
https://developer.paypal.com/docs/
在使用checkout api文档的时候,最好是用搜索找东西:
https://developer.paypal.com/docs/api/overview/
使用文档的一个小例子,比如使用以下地址:
https://developer.paypal.com/docs/api/payments/v1/
如果右侧的代码上边有这些按钮:
可以点击进去看看示例代码。
paypal IPN通知:
https://developer.paypal.com/docs/notifications/#ipn?mark=ipn