Hướng dẫn paypal-php id

Mở đầu

Cài đặt

Tạo Paypal sandbox

Để thực hiện các cuộc gọi đến PayPal API chúng ta cần phải tạo ra một ứng dụng trong developer.paypal.com.

  1. Đăng nhập bằng tài khoản nhà phát triển vào trang PayPal’s Developer. Nếu bạn đang truy cập lần đầu tiên, hãy đăng ký và tạo một tài khoản mới.
  2. Sau khi đăng nhập, bạn sẽ được chuyển hướng đến trang các ứng dụng của tôi, ở đó bạn có thể tạo một ứng dụng mới ở https://developer.paypal.com/developer/applications/create

Hướng dẫn paypal-php id

  1. Điền tên ứng dụng, chọn tài khoản Sandbox Business account và bấm vào tạo ứng dụng. Một khi các ứng dụng được tạo ra, bạn có thể nhận thấy Client id & Secret. Chúng ta sẽ cần các thành phần này cho đồng thời server và ứng dụng client. Bạn có thể chỉnh sửa các feature cho Paypal app, trong bài viết này Sandbox app của mình sử dụng các feature này

Hướng dẫn paypal-php id

Init project

Trước tiên của init 1 project Laravel trước cho chắc =))

Công việc này khá là quen thuộc với các bạn đã làm việc với Laravel, chúng ta cần clone Laravel app từ Github về bằng các command dưới đây :

$ git clone :laravel/laravel.git my-laravel
$ cd my-laravel
$ cp .env.example .env
$ sudo chmod -R 777 storage/
$ composer install

Trong dự án này mình sử dụng package srmklive/paypal để tương tác với API của Paypal bằng cách chạy lệnh

$ composer require srmklive/paypal:~3.0

sau bước này chúng ta sẽ thêm 1 file config cho package vào trong config/paypal.php với nội dung như sau

<?php
/**
 * PayPal Setting & API Credentials
 * Created by Raza Mehdi <>.
 */

return [
    'mode' => env('PAYPAL_MODE', 'live'), // Can only be 'sandbox' Or 'live'. If empty or invalid, 'live' will be used.
    'client_id' => env('PAYPAL_CLIENT_ID', ''),
    'client_secret' => env('PAYPAL_CLIENT_SECRET', ''),
    'app_id' => env('PAYPAL_APP_ID', ''),
    'payment_action' => env('PAYPAL_PAYMENT_ACTION', 'Sale'), // Can only be 'Sale', 'Authorization' or 'Order'
    'currency' => env('PAYPAL_CURRENCY', 'AUD'),
    'notify_url' => env('PAYPAL_NOTIFY_URL', ''), // Change this accordingly for your application.
    'locale' => env('PAYPAL_LOCALE', 'en_US'), // force gateway language  i.e. it_IT, es_ES, en_US ... (for express checkout only)
    'validate_ssl' => env('PAYPAL_VALIDATE_SSL', true), // Validate SSL when creating api client.
    'webhook_id' => env('PAYPAL_WEBHOOK_ID', ''),
    'gateway_url' => env('PAYPAL_MODE', 'live') === 'sandbox' ? 'https://www.sandbox.paypal.com' : 'https://www.paypal.com',
];

Nếu tham khảo trên doc của package thì file config/paypal.php của package này xây dựng sẵn sẽ hơi khác, nhưng vì mình không thích cách cấu hình đấy nên mình flat hết chúng ra luôn

Hướng dẫn paypal-php id

Tiếp theo bạn sử dụng ClientID & Secrets vừa tạo ở trên bổ sung vào trong .env

#PayPal Setting & API Credentials
PAYPAL_MODE=sandbox
PAYPAL_CLIENT_ID=xxx
PAYPAL_CLIENT_SECRET=xx-xxx
PAYPAL_WEBHOOK_ID=xxx

Thanh toán cho 1 order

Xây dựng API create order

Tiếp theo chúng ta tiến hành xây dựng controller để xử lý việc thanh toán cho 1 order. Trước tiên chúng ta cần setup cho package 1 chút, bởi vì mình có thay đổi lại file config/paypal.php một chút

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Srmklive\PayPal\Services\PayPal;

class PaymentController extends Controller
{
    private PayPal $paypal;

    public function __construct(PayPal $paypal)
    {
        $this->paypal = $paypal;
        $this->paypal->setApiCredentials($this->buildPaypalConfig(config('paypal')));
        $this->paypal->setAccessToken($this->paypal->getAccessToken());
    }
    
    public function buildPaypalConfig($config)
    {
        return [
            'mode' => data_get($config, 'mode'),
            'sandbox' => [
                'client_id' => data_get($config, 'client_id'),
                'client_secret' => data_get($config, 'client_secret'),
                'app_id' => data_get($config, 'app_id'),
            ],
            'live' => [
                'client_id' => data_get($config, 'client_id'),
                'client_secret' => data_get($config, 'client_secret'),
                'app_id' => data_get($config, 'app_id'),
            ],

            'payment_action' => data_get($config, 'payment_action'),
            'currency' => data_get($config, 'currency'),
            'notify_url' => data_get($config, 'notify_url'),
            'locale' => data_get($config, 'locale'),
            'validate_ssl' => data_get($config, 'validate_ssl'),
            'webhook_id' => data_get($config, 'webhook_id'),
        ];
    }
}
    
  • Do mình sử dụng use Srmklive\PayPal\Services\PayPal; nên trong __constructor chúng ta cần setApiCredentials và setAccessToken cho provider này
  • Func buildPaypalConfig($config) sẽ thực hiện map config sang cấu trúc mà package cần đế sử dụng

Đầu tiên với API create order

public function createOrder(Request $request)
    {
        $paypalOrder = $this->paypal->createOrder([
            'intent'=> 'CAPTURE',
            'application_context' => [
                'brand_name' => config('app.name'),
                'landing_page' => 'BILLING',
                "user_action" => "PAY_NOW",
            ],
            'purchase_units' => [
                [
                    'amount' => [
                        'currency_code' => 'USD',
                        'value' => '100.00'
                    ],
                ],
            ],
        ]);

        // Thêm logic lưu thông tin order vào DB
        return $paypalOrder;
    }

Với API capture order, đơn giản hơn chúng ta chỉ cần gọi tới paypal API để capture trạng thái của order vừa tạo

public function captureOrder($orderId)
    {
        $capturedOrder = $this->paypal->capturePaymentOrder($orderId);

        // Thêm logic cập nhập thông tin order vào DB

        return $capturedOrder;
    }
    

Thông tin về captureOrder chứa trạng thái order, số tiền mà payer đã thanh toán và nhiều thông tin các nữa

Hướng dẫn paypal-php id

Thanh toán cho 1 subscription

Subscription là một chức năng thích hợp cho các sản phẩm có yêu cầu nghiệp vụ là phải gia hạn hằng tháng hoặc hàng tuần chẳng hạn. Đối với những dịch vụ này, việc website chúng ta chủ động yêu cầu ngừoi dùng bấm lại nút thanh toán sẽ gây phiền toái khá nhiều, vì vậy Paypal đã hỗ trợ việc tự động thanh toán hằng tháng.

Để tích hợp được chức năng này cho website, chúng ta cần follow qua các bước

  • Đầu tiên chúng ta cần tạo các Subscription Plan trên giao diện Paypal bằng việc tài khoản Business
  • Sau đó ở phía website sẽ sử dụng Paypal API tiến hành subscribe người dùng tới Plan vừa tạo
  • Mỗi chu kỳ thanh toán, chúng ta sẽ nhận được Notification từ paypal về trạng thái thanh toán của Subscription đó.

Tạo Subscription plan trên Paypal

Đầu tiên chúng ta cần tạo các Subscription Plan trên giao diện Paypal bằng việc truy cập tài khoản Business, vì mình đang ở môi trường dev qua Sandbox nên mình truy cập địa chỉ này https://www.sandbox.paypal.com/billing/plans/plan/create/choose-product?from=plans

Vì mỗi plan sẽ yêu cầu bạn tạo kèm 1 hoặc 1 số Product nên bạn cần fill kha khá thông tin. Sau khi tạo thành công chúng ta sẽ có được 1 Plan như này

Hướng dẫn paypal-php id

Có rất nhiều thông tin, nhưng chúng ta chỉ cần quan tâm Plan ID thôi.

Demo thanh toán Subscription

Hướng dẫn paypal-php id

Tạm kết

Hy vọng bài viết này sẽ giúp các bạn giải quyết được chút khó khăn khi tích hợp chức năng thanh toán với Paypal, trong bài viết tới mình sẽ bổ sung thêm những use case khác liên quan tới Paypal, các bạn đón đọc nhé

Tham khảo

  • Github repository: https://github.com/daothaison/paypal-checkout-demo