zehntech/paypal

这是一个用于 PayPal 适应性支付(链式支付)的包

dev-master 2020-01-28 09:40 UTC

This package is auto-updated.

Last update: 2024-09-28 20:35:41 UTC


README

简介

通过使用此插件,您可以在 Laravel 应用程序中处理或退款支付,并处理 PayPal 的 IPN(即时支付通知)。

目前仅支持 PayPal 快速结账 API。

GitHub 仓库 https://github.com/osingh152/paypal

PayPal API 凭证

此包使用经典的 PayPal 快速结账。有关如何创建 API 凭证的说明,请参阅此链接

https://developer.paypal.com/docs/classic/api/apiCredentials/#create-an-api-signature

安装

  • 使用以下命令安装
composer require zehntech/paypal
  • 将服务提供者添加到您的 $providers 数组中的 config/app.php 文件,如下所示
Zehntech\Paypal\Providers\PayPalServiceProvider::class
  • 将别名添加到您的 $aliases 数组中的 config/app.php 文件,如下所示
'PayPal' => Zehntech\PayPal\Facades\PayPal::class
  • 运行以下命令以发布配置
php artisan vendor:publish --provider "Zehntech\Paypal\Providers\PayPalServiceProvider"

配置

  • 安装后,您需要添加您的 PayPal 设置。以下是在 config/paypal.php 中找到的代码,您应该相应地更新它。
return [
    'mode'    => 'sandbox', // Can only be 'sandbox' Or 'live'. If empty or invalid, 'live' will be used.
    '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', // Used for testing Adaptive Payments API in sandbox mode
    ],
    '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'      => '', // Used for Adaptive Payments API
    ],

    'payment_action' => 'Sale', // Can only be 'Sale', 'Authorization' or 'Order'
    'currency'       => 'USD',
    'notify_url'     => '', // Change this accordingly for your application.
    'locale'         => '', // force gateway language  i.e. it_IT, es_ES, en_US ... (for express checkout only)
    'validate_ssl'   => true, // Validate SSL when creating api client.
];
  • 将其添加到 .env.example.env
#PayPal Setting & API Credentials - sandbox
PAYPAL_SANDBOX_API_USERNAME=
PAYPAL_SANDBOX_API_PASSWORD=
PAYPAL_SANDBOX_API_SECRET=
PAYPAL_SANDBOX_API_CERTIFICATE=

#PayPal Setting & API Credentials - live
PAYPAL_LIVE_API_USERNAME=
PAYPAL_LIVE_API_PASSWORD=
PAYPAL_LIVE_API_SECRET=
PAYPAL_LIVE_API_CERTIFICATE=

用法

以下是通过以下方式访问 PayPal 提供者的几种方法

// Import the class namespaces first, before using it directly
use Srmklive\PayPal\Services\ExpressCheckout;
use Srmklive\PayPal\Services\AdaptivePayments;

$provider = new ExpressCheckout;      // To use express checkout.
$provider = new AdaptivePayments;     // To use adaptive payments.

// Through facade. No need to import namespaces
$provider = PayPal::setProvider('express_checkout');      // To use express checkout(used by default).
$provider = PayPal::setProvider('adaptive_payments');     // To use adaptive payments.

覆盖 PayPal API 配置

您可以通过调用 setApiCredentials 方法来覆盖 PayPal API 配置

$provider->setApiCredentials($config);

设置货币

默认使用的货币是 USD。如果您想更改它,您可以在调用任何相应的 API 方法之前调用 setCurrency 方法来设置不同的货币

$provider->setCurrency('EUR')->setExpressCheckout($data);

额外的 PayPal API 参数

默认情况下,仅使用 PayPal API 调用的特定参数集。但是,如果您想指定其他任何附加参数,您可以在调用任何相应的 API 方法之前调用 addOptions 方法

$options = [
    'BRANDNAME' => 'MyBrand',
    'LOGOIMG' => 'https://example.com/mylogo.png',
    'CHANNELTYPE' => 'Merchant'
];

$provider->addOptions($options)->setExpressCheckout($data);

注意:任何参数应相应地引用您将执行的 API 调用。例如,如果您正在执行 SetExpressCheckout,则必须提供 PayPal 为 SetExpressCheckout 记录的参数,以便传递给 addOptions 方法。

快速结账

$data = [];
$data['items'] = [
    [
        'name' => 'Product 1',
        'price' => 9.99,
        'desc'  => 'Description for product 1'
        'qty' => 1
    ],
    [
        'name' => 'Product 2',
        'price' => 4.99,
        'desc'  => 'Description for product 2',
        'qty' => 2
    ]
];

$data['invoice_id'] = 1;
$data['invoice_description'] = "Order #{$data['invoice_id']} Invoice";
$data['return_url'] = url('/payment/success');
$data['cancel_url'] = url('/cart');

$total = 0;
foreach($data['items'] as $item) {
    $total += $item['price']*$item['qty'];
}

$data['total'] = $total;

//give a discount of 10% of the order amount
$data['shipping_discount'] = round((10 / 100) * $total, 2);

  • SetExpressCheckout

    $response = $provider->setExpressCheckout($data);
    
    // Use the following line when creating recurring payment profiles (subscriptions)
    $response = $provider->setExpressCheckout($data, true);
    
     // This will redirect user to PayPal
    return redirect($response['paypal_link']);

  • GetExpressCheckoutDetails

    $response = $provider->getExpressCheckoutDetails($token);

  • DoExpressCheckoutPayment

    // Note that 'token', 'PayerID' are values returned by PayPal when it redirects to success page after successful verification of user's PayPal info.
    $response = $provider->doExpressCheckoutPayment($data, $token, $PayerID);

  • RefundTransaction

    $response = $provider->refundTransaction($transactionid);
    
    // To issue partial refund, you must provide the amount as well for refund:
    $response = $provider->refundTransaction($transactionid, 9.99);      

  • CreateBillingAgreement

    // The $token is the value returned from SetExpressCheckout API call
    $response = $provider->createBillingAgreement($token);

  • DoReferenceTransaction

    // The $token is the value returned from CreateBillingAgreement API call
    // $action Can be Order, Sale or Authorization
    // $amount to withdraw from the given BillingAgreement defaults to $. To overwrite use $provider->addOptions
    $response = $provider->doReferenceTransaction($token,$action,$amount);

  • GetTransactionDetails

    // The $token is the value returned from doReferenceTransaction API call
    $response = $provider->getTransactionDetails($token);

  • CreateRecurringPaymentsProfile

    // The $token is the value returned from SetExpressCheckout API call
    $startdate = Carbon::now()->toAtomString();
    $profile_desc = !empty($data['subscription_desc']) ?
                $data['subscription_desc'] : $data['invoice_description'];
    $data = [
        'PROFILESTARTDATE' => $startdate,
        'DESC' => $profile_desc,
        'BILLINGPERIOD' => 'Month', // Can be 'Day', 'Week', 'SemiMonth', 'Month', 'Year'
        'BILLINGFREQUENCY' => 1, // 
        'AMT' => 10, // Billing amount for each billing cycle
        'CURRENCYCODE' => 'USD', // Currency code 
        'TRIALBILLINGPERIOD' => 'Day',  // (Optional) Can be 'Day', 'Week', 'SemiMonth', 'Month', 'Year'
        'TRIALBILLINGFREQUENCY' => 10, // (Optional) set 12 for monthly, 52 for yearly 
        'TRIALTOTALBILLINGCYCLES' => 1, // (Optional) Change it accordingly
        'TRIALAMT' => 0, // (Optional) Change it accordingly
    ];
    $response = $provider->createRecurringPaymentsProfile($data, $token);

  • GetRecurringPaymentsProfileDetails

    $response = $provider->getRecurringPaymentsProfileDetails($profileid);

  • UpdateRecurringPaymentsProfile

    $response = $provider->updateRecurringPaymentsProfile($data, $profileid);

  • ManageRecurringPaymentsProfileStatus

    // Cancel recurring payment profile
    $response = $provider->cancelRecurringPaymentsProfile($profileid);
    
    // Suspend recurring payment profile
    $response = $provider->suspendRecurringPaymentsProfile($profileid);
    
    // Reactivate recurring payment profile
    $response = $provider->reactivateRecurringPaymentsProfile($profileid);    

适应性支付

要使用适应性支付,您必须将提供者设置为使用适应性支付

PayPal::setProvider('adaptive_payments');

  • 主支付
// Change the values accordingly for your application
$data = [
    'receivers'  => [
        [
            'email' => 'johndoe@example.com',
            'amount' => 10,
            'primary' => true,
        ],
        [
            'email' => 'janedoe@example.com',
            'amount' => 5,
            'primary' => false
        ]
    ],
	'action_type' => 'PAY_PRIMARY',
    'payer' => 'EACHRECEIVER', // (Optional) Describes who pays PayPal fees. Allowed values are: 'SENDER', 'PRIMARYRECEIVER', 'EACHRECEIVER' (Default), 'SECONDARYONLY'
    'return_url' => url('payment/success'), 
    'cancel_url' => url('payment/cancel'),
];

$response = $provider->createPayRequest($data);

// The above API call will return the following values if successful:
// 'responseEnvelope.ack', 'payKey', 'paymentExecStatus'

接下来,您需要将用户重定向到 PayPal 以授权支付

$redirect_url = $provider->getRedirectUrl('approved', $response['payKey']);

return redirect($redirect_url);

  • 次支付
// Change the values accordingly for your application

$payKey='Your payment paykey';
$actioType='Pay';
$response = $provider->approvePayment($payKey, $actioType);

处理 PayPal IPN

您还可以处理 PayPal 的即时支付通知。假设您已在 PayPal 中将 IPN URL 设置为 http://example.com/ipn/notify/。要处理 IPN,您应执行以下操作

  • 首先将 ipn/notify 添加到您的路由文件中

    Route::post('ipn/notify','PayPalController@postNotify'); // Change it accordingly in your application
  • 打开 App\Http\Middleware\VerifyCsrfToken.php 并将您的 IPN 路由添加到 $excluded 路由变量中。

    'ipn/notify'
  • 在您将解析 IPN 响应的函数中编写以下代码

    /**
     * Retrieve IPN Response From PayPal
     *
     * @param \Illuminate\Http\Request $request
     */
    public function postNotify(Request $request)
    {
        // Import the namespace Srmklive\PayPal\Services\ExpressCheckout first in your controller.
        $provider = new ExpressCheckout;
        
        $request->merge(['cmd' => '_notify-validate']);
        $post = $request->all();        
        
        $response = (string) $provider->verifyIPN($post);
        
        if ($response === 'VERIFIED') {                      
            // Your code goes here ...
        }                            
    }        

创建订阅

  • 例如,您想在 PayPal 上创建一个周期性订阅,首先以以下格式将数据传递给 SetExpressCheckout API 调用
// Always update the code below accordingly to your own requirements.
$data = [];

$data['items'] = [
    [
        'name'  => "Monthly Subscription",
        'price' => 0,
        'qty'   => 1,
    ],
];

$data['subscription_desc'] = "Monthly Subscription #1";
$data['invoice_id'] = 1;
$data['invoice_description'] = "Monthly Subscription #1";
$data['return_url'] = url('/paypal/ec-checkout-success?mode=recurring');
$data['cancel_url'] = url('/');

$total = 0;
foreach ($data['items'] as $item) {
    $total += $item['price'] * $item['qty'];
}

$data['total'] = $total;

//give a discount of 10% of the order amount
$data['shipping_discount'] = round((10 / 100) * $total, 2);
$amount = 9.99;
$description = "Monthly Subscription #1";
$response = $provider->createMonthlySubscription($token, $amount, $description);

// To create recurring yearly subscription on PayPal
$response = $provider->createYearlySubscription($token, $amount, $description);

支持

此插件仅支持Laravel 5.1或更高版本。

  • 如遇任何问题,请在问题部分创建一个。
  • 如果您想做出贡献
    • 将此仓库进行Fork。
    • 实现您的功能。
    • 生成pull request。