https://developer.paypal.com/developer/accounts/ ,会给你分配两个账户,一个个人,一个公司,点击profile,设置密码,点击save,买家账户里面有9000美金,测试用,够用了;
进入 https://developer.paypal.com/developer/applications/ 创建应用,获取client_id和secret;
composer require paypal/rest-api-sdk-php
写一个最简单的页面,我用的是laravel框架,其他的php框架类似:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>支付页面</title>
</head>
<body>
<div>
@php
$price=mt_rand(1,100)/100;
$products=['鞋子', '帽子', '衣服', '华为手机', '小米手机', '变形金刚'];
$product=$products[array_rand($products)];
$quantity=mt_rand(1,3);
@endphp
<form action="{{ url('paypal/checkout') }}" method="post" autocomplete="off">
{{ csrf_field() }}
<label for="item">
产品名称
<input type="text" name="product_name" value="{{$product}}">
</label>
<br>
<label for="amount">
价格
<input type="text" name="price" value="{{$price}}">
</label>
<br>
<label for="quantity">
数量
<input type="number" name="quantity" value="{{$quantity}}">
</label>
<br>
<input type="submit" value="去付款">
</form>
</div>
</body>
</html>
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use PayPal\Api\Amount;
use PayPal\Api\Details;
use PayPal\Api\Item;
use PayPal\Api\ItemList;
use PayPal\Api\Payer;
use PayPal\Api\Payment;
use PayPal\Api\PaymentExecution;
use PayPal\Api\RedirectUrls;
use PayPal\Api\Refund;
use PayPal\Api\Sale;
use PayPal\Api\Transaction;
use PayPal\Exception\PayPalConnectionException;
use Validator;
class PaypalController extends Controller
{
private $paypal;
private $client_id;
private $secret;
public function __construct()
{
$this->client_id = config('pay.paypal.client_id');
$this->secret = config('pay.paypal.secret');
$this->paypal = new \PayPal\Rest\ApiContext(
new \PayPal\Auth\OAuthTokenCredential(
$this->client_id,
$this->secret
));
#设置日志
$this->paypal->setConfig(
array(
'log.LogEnabled' => true,
'log.FileName' => '../storage/logs/paypal.log',
'log.LogLevel' => 'DEBUG',
// 'mode' => 'live',
)
);
}
public function paypalProductionPage()
{
return view('pay.paypal');
}
/**
* 去付款的页面
* @param Request $request [description]
* @param Request $request [description]
* @param price 单价 [description]
* @param method $request [Valid Values: ["credit_card", "bank", "paypal", "pay_upon_invoice", "carrier", "alternate_payment"]]
* @return [type] [description]
*/
public function checkout(Request $request)
{
$validator = Validator::make($request->all(), [
'product_name' => 'required|string|min:2|max:64',
'price' => 'required|numeric|min:0',
'method' => 'nullable|in:credit_card, bank, paypal, pay_upon_invoice, carrier, alternate_payment',
'shipping' => 'nullable|numeric|min:0|max:9999',
'quantity' => 'required|integer|min:1',
'currency' => 'nullable|in:EUR,USD',
]);
if ($validator->fails()) {
$error = $validator->errors()->first();
return $this->outPutJson('', 201, $error);
}
//买家账户 [email protected] ,密码:test123456
$product_name = request('product_name', 0);
$price = request('price', 0);
$method = request('method', 'paypal');
$shipping = request('shipping', 0.0);
$quantity = request('quantity', 1);
$currency = request('currency', 'EUR');
$subtotal = $quantity * $price;
$total = $subtotal + $shipping;
$payer = new Payer();
$payer->setPaymentMethod($method); #设置支付方式
$item = new Item();
$item->setName($product_name)
->setCurrency($currency)
->setQuantity($quantity)
->setPrice($price);
$itemList = new ItemList();
$itemList->setItems([$item]);
$details = new Details();
$details->setShipping($shipping)
->setSubtotal($subtotal);
$amount = new Amount();
$amount->setCurrency($currency)
->setTotal($total)
->setDetails($details);
$transaction = new Transaction();
$transaction->setAmount($amount)
->setItemList($itemList)
->setDescription("买东西测试环境")
->setInvoiceNumber(uniqid());
// dd($amount, $transaction);
$redirectUrls = new RedirectUrls();
$redirectUrls->setReturnUrl(config('pay.paypal.notify_url') . '?success=true')
->setCancelUrl(config('pay.paypal.notify_url') . '?success=false');
$payment = new Payment();
$payment->setIntent('sale') #"sale", "authorize", "order"
->setPayer($payer)
->setRedirectUrls($redirectUrls)
->setTransactions([$transaction]);
try {
$payment->create($this->paypal);
$approvalUrl = $payment->getApprovalLink();
header("Location: {$approvalUrl}");
} catch (PayPalConnectionException $e) {
return $this->outPutJson('', 201, $e->getData());
}
}
/**
* 回调地址,支付成功或者失败要跳转的地址
* @param Request $request [description]
* @return [type] [description]
*/
public function notify(Request $request)
{
$validator = Validator::make($request->all(), [
'success' => 'required|in:true,false',
'paymentId' => 'required|string|min:8|max:32',
'PayerID' => 'required|string|min:8|max:32',
]);
if ($validator->fails()) {
$error = $validator->errors()->first();
return $this->outPutJson('', 201, $error);
}
if (request('success') === false) {
return $this->outPutJson('', 206, '取消支付!');
}
$paymentID = request('paymentId');
$payerId = request('PayerID');
$payment = Payment::get($paymentID, $this->paypal);
$execute = new PaymentExecution();
$execute->setPayerId($payerId);
try {
$result = $payment->execute($execute, $this->paypal);
/*获取sale_id*/
$transactions = $payment->getTransactions();
$related_resources = $transactions[0]->getRelatedResources();
$sale = $related_resources[0]->getSale();
$sale_id = $sale->getId();
Log::info('sale_id是:' . $sale_id); #把这个id存到数据库
/**/
dd($result, $sale_id); #付款成功之后会有sale_id
} catch (\Exception $e) {
return $this->outPutJson('', 500, '支付失败!错误如下:' . $e->getMessage());
}
return $this->outPutJson('', 200, '支付成功!感谢支持!');
}
/**
* 退款接口
* @param Request $request [description]
* @return [type] [description]
*/
public function refund(Request $request)
{
$validator = Validator::make($request->all(), [
'sale_id' => 'required|string|min:2|max:64',
'currency' => 'nullable|in:EUR,USD',
'total' => 'required|numeric|min:0',
]);
if ($validator->fails()) {
$error = $validator->errors()->first();
return $this->outPutJson('', 201, $error);
}
$currency = request('currency', 'EUR');
$total = request('total', 0.01);
$sale_id = request('sale_id', ' 5V891731LF6603604'); #已退款
$amt = new Amount();
$amt->setTotal($total)
->setCurrency($currency);
$refund = new Refund();
$refund->setAmount($amt);
$sale = new Sale();
$sale->setId($sale_id);
try {
$refundedSale = $sale->refund($refund, $this->paypal);
return $this->outPutJson('', 200, '退款成功!');
dd($refundedSale);
} catch (PayPalConnectionException $ex) {
// $ex->getCode()返回400表示没找到这个订单,这个订单可能已经退款,可能还没创建,404非法sale_id
// dd($ex->getCode(), $ex->getData());
return $this->outPutJson('', 405, '退款失败!');
} catch (\Exception $ex) {
return $this->outPutJson('', 500);
// die($ex);
}
}
}
点击去付款,会让你填入账号密码,填入买家邮箱和密码,点击登陆
文档地址:
https://developer.paypal.com/developer/accountStatus/
https://developer.paypal.com/docs/api/quickstart/#
完整代码:
https://paypal.github.io/PayPal-PHP-SDK/sample/doc/payments/CreatePaymentUsingPayPal.html
官方示例代码:
http://paypal.github.io/PayPal-PHP-SDK/sample/