namespace app\services;
use PayPal\Api\Amount; use PayPal\Api\Details; use PayPal\Api\FlowConfig; use PayPal\Api\Payer; use PayPal\Api\Payment; use PayPal\Api\PaymentExecution; use PayPal\Api\RedirectUrls; use PayPal\Api\RefundRequest; use PayPal\Api\Sale; use PayPal\Api\Transaction;
class PayPalService { private $clientId;
private $clientSecret;
private $is_live = false;
private $returnUrl;
private $cancelUrl;
private $notifyUrl;
private $currency;
public function __construct() { $this->clientId = ''; $this->clientSecret = ''; $this->currency = 'USD'; $this->returnUrl = ''; $this->cancelUrl = ''; $this->notifyUrl = ''; }
public function createOrder(array $params): array { [ 'order_sn' => $order_sn, 'description' => $description, 'total' => $total, 'subtotal' => $subtotal, 'shipping' => $shipping, 'shipping_discount' => $shipping_discount, 'handling_fee' => $handling_fee, 'insurance' => $insurance, 'tax' => $tax, ] = $params; $demo_params = [ 'order_sn' => '', 'description' => '', 'total' => '', 'subtotal' => '', 'shipping' => '', 'shipping_discount' => '', 'handling_fee' => '', 'insurance' => '', 'tax' => '', ];
$apiContext = new \PayPal\Rest\ApiContext( new \PayPal\Auth\OAuthTokenCredential( $this->clientId, $this->clientSecret ) );
if ($this->is_live) { $apiContext->setConfig(array('mode'=>'live')); }
$flow = new FlowConfig(); $flow->setLandingPageType('Billing');
$payer = new Payer(); $payer -> setPaymentMethod('paypal');
$redirectUrls = new RedirectUrls(); $redirectUrls -> setReturnUrl($this->returnUrl) -> setCancelUrl($this->cancelUrl);
$details = new Details();
$shipping_discount && $details->setShippingDiscount($shipping_discount); $handling_fee && $details->setHandlingFee($handling_fee); $insurance && $details->setInsurance($insurance); $tax && $details->setTax($tax);
$details->setShipping($shipping) ->setSubtotal($subtotal);
$amount = new Amount(); $amount->setCurrency($this->currency)->setTotal($total)->setDetails($details);
$transaction = new Transaction(); $transaction -> setAmount($amount) -> setDescription($description) -> setInvoiceNumber($order_sn);
$this->notifyUrl && $transaction->setNotifyUrl($this->notifyUrl);
$payment = new Payment(); $payment -> setIntent('sale') -> setPayer($payer) -> setRedirectUrls($redirectUrls) -> setTransactions(array($transaction));
try{
$payment -> create($apiContext); $approval_url = $payment -> getApprovalLink(); return compact('approval_url');
} catch(\PayPal\Exception\PayPalConnectionException $ex){ \Yii::error('PayPalConnectionException: '. $ex->getCode().' --- '.$ex->getData()); throw $ex;
} catch (\Exception $ex){ throw $ex; } }
public function execute(string $payerId, string $paymentId): array { $apiContext = new \PayPal\Rest\ApiContext( new \PayPal\Auth\OAuthTokenCredential( $this->clientId, $this->clientSecret ) );
if ($this->is_live) { $apiContext->setConfig(array('mode'=>'live')); }
$payment = Payment::get($paymentId, $apiContext); $execution = new PaymentExecution(); $execution -> setPayerId($payerId);
try { $result = $payment -> execute($execution, $apiContext); return json_decode($result->toJSON(128), true); } catch (\PayPal\Exception\PayPalConnectionException $ex) { throw $ex; } catch (\Exception $ex){ throw $ex; } }
public function query(string $sale_id) { $apiContext = new \PayPal\Rest\ApiContext( new \PayPal\Auth\OAuthTokenCredential( $this->clientId, $this->clientSecret ) );
if ($this->is_live) { $apiContext->setConfig(array('mode'=>'live')); }
try { $demo_result = '{"id":"1DU410917H5745019","state":"completed","amount":{"total":"0.99","currency":"USD","details":{"subtotal":"0.99"}},"payment_mode":"INSTANT_TRANSFER","protection_eligibility":"ELIGIBLE","protection_eligibility_type":"ITEM_NOT_RECEIVED_ELIGIBLE,UNAUTHORIZED_PAYMENT_ELIGIBLE","transaction_fee":{"value":"0.33","currency":"USD"},"invoice_number":"HM4cf42be81cf793d8c7b54a01e99e87","parent_payment":"PAYID-MFIBXZQ2F2665569K055620G","create_time":"2021-09-26T07:06:32Z","update_time":"2021-09-26T07:06:32Z","links":[{"href":"https://api.sandbox.paypal.com/v1/payments/sale/1DU410917H5745019","rel":"self","method":"GET"},{"href":"https://api.sandbox.paypal.com/v1/payments/sale/1DU410917H5745019/refund","rel":"refund","method":"POST"},{"href":"https://api.sandbox.paypal.com/v1/payments/payment/PAYID-MFIBXZQ2F2665569K055620G","rel":"parent_payment","method":"GET"}]}'; $result = Sale::get($sale_id, $apiContext);
} catch (\Exception $exception) { print($exception); exit(); }
return json_decode($result->toJSON(128), true); }
public function refund(string $sale_id, string $refund_money) { $amt = new Amount(); $amt->setCurrency($this->currency) ->setTotal($refund_money);
$refundRequest = new RefundRequest(); $refundRequest->setAmount($amt);
$sale = new Sale(); $sale->setId($sale_id);
$apiContext = new \PayPal\Rest\ApiContext( new \PayPal\Auth\OAuthTokenCredential( $this->clientId, $this->clientSecret ) );
if ($this->is_live) { $apiContext->setConfig(array('mode'=>'live')); }
try { $demo_result = '{"id":"9WW2694970862104R","state":"completed","amount":{"total":"0.99","currency":"USD"},"refund_from_received_amount":{"value":"0.96","currency":"USD"},"refund_from_transaction_fee":{"value":"0.03","currency":"USD"},"total_refunded_amount":{"value":"0.99","currency":"USD"},"parent_payment":"PAYID-MFIBXZQ2F2665569K055620G","sale_id":"1DU410917H5745019","create_time":"2021-09-27T03:39:25Z","update_time":"2021-09-27T03:39:25Z","links":[{"href":"https://api.sandbox.paypal.com/v1/payments/refund/9WW2694970862104R","rel":"self","method":"GET"},{"href":"https://api.sandbox.paypal.com/v1/payments/payment/PAYID-MFIBXZQ2F2665569K055620G","rel":"parent_payment","method":"GET"},{"href":"https://api.sandbox.paypal.com/v1/payments/sale/1DU410917H5745019","rel":"sale","method":"GET"}]}'; $result = $sale->refundSale($refundRequest, $apiContext); } catch (\Exception $exception) { print($exception); exit(); }
return json_decode($result->toJSON(128), true); }
public function notify(array $data) { $demo_data = [ 'mc_gross' => '0.02', 'invoice' => '614d8f401d847', 'protection_eligibility' => 'Eligible', 'address_status' => 'confirmed', 'payer_id' => 'KJSDP2SHURBL4', 'address_street' => 'NO 1 Nan Jin Road', 'payment_date' => '01:42:04 Sep 24, 2021 PDT', 'payment_status' => 'Completed', 'charset' => 'gb2312', 'address_zip' => '200000', 'first_name' => 'John', 'mc_fee' => '0.02', 'address_country_code' => 'CN', 'address_name' => 'Doe John', 'notify_version' => '3.9', 'custom' => '', 'payer_status' => 'verified', 'business' => 'sb-oarsk7805857@business.example.com', 'address_country' => 'China', 'address_city' => 'Shanghai', 'quantity' => '1', 'verify_sign' => 'A-on.2dE-HD0drM32ZIE1tBYMyPgAwyGxgTmK4t-mnBRnYKgqGgp0Ens', 'payer_email' => 'sb-fkppe7805825@personal.example.com', 'txn_id' => '78H69914TW0115549', 'payment_type' => 'instant', 'last_name' => 'Doe', 'address_state' => 'Shanghai', 'receiver_email' => 'sb-oarsk7805857@business.example.com', 'payment_fee' => '0.02', 'shipping_discount' => '0.00', 'insurance_amount' => '0.00', 'receiver_id' => 'TY6C65BAP5JD6', 'txn_type' => 'express_checkout', 'item_name' => 'Testing Request', 'discount' => '0.00', 'mc_currency' => 'USD', 'item_number' => '', 'residence_country' => 'CN', 'test_ipn' => '1', 'shipping_method' => 'Default', 'transaction_subject' => 'Testing Request', 'payment_gross' => '0.02', 'shipping' => '0.00', 'ipn_track_id' => '8aac94e9740a0', ];
if (strtolower($data['payment_status']) === 'completed') {
$order = $this->query($data['txn_id']); if ($order['state'] !== 'completed') { throw new \Exception('PayPal订单状态异常'); }
} } }
|