Giter Club home page Giter Club logo

alipay-global-sdk-php's Introduction

Alipay Global SDK PHP

Alipay Global A+ SDK

This project is based on Alipay Global Offical PHP SDK
Since official SDK mainly shows how to access the alipay gateway and does not contain complete functions such as authorization and auto debit, I have added some logic and further realized the standard interface of Alipay Global A+

Attention!

0.0.3+: sendNotifyResponse sendNotifyResponseWithRSA are methods of $notify, eg:

$notify = $alipayGlobal->getNotify();
$notify->sendNotifyResponse(); // $alipayGlobal->sendNotifyResponse() is desprecated
$notify->sendNotifyResponseWithRSA(); // $alipayGlobal->sendNotifyResponseWithRSA() is desprecated
/* getNotifyResponse and getNotifyResponseWithRSA are added,
   so you can process it by yourself in memory frameworks like Webman */
$notifyResponseWithRSA =  $notify->getNotifyResponse();
$notifyResponseWithRSA =  $notify->getNotifyResponseWithRSA();

Demo

The use and functionality of the SDK have been shown with Examples in the project folder

Use

composer require mantoufan/alipay-global-sdk-php

How to use

Initialize

$alipayGlobal = new Mantoufan\AliPayGlobal(array(
    'client_id' => 'SANDBOX_5Y3A2N2YEB3002022', // Client ID
    'endpoint_area' => 'ASIA', // Optional: NORTH_AMERIA / ASIA / EUROPE
    'merchantPrivateKey' => '', // Merchant Private Key
    'alipayPublicKey' => '', // Alipay Public Key
    'is_sandbox' => true, // Whether to use the Sandbox environment
));

Required fields will be mark with *

Online payment - Payment - Pay (Cashier Payment)

API: ac/ams/payment_cashier
DEMO: pay/cashier

use Mantoufan\model\CustomerBelongsTo;
use Mantoufan\model\TerminalType;
try {
  $result = $alipayGlobal->payCashier(array(
      'customer_belongs_to' => CustomerBelongsTo::ALIPAY_CN, // * Users pay with Alipay Chinese wallet,Optional: ALIPAY_CN / ALIPAY_HK / TRUEMONEY / TNG / GCASH / DANA / KAKAOPAY / EASYPAISA / BKASH
      'notify_url' => '', // Asynchronous callback Url
      'return_url' => '', // Synchronize callback Url
      'amount' => array(
          'currency' => 'USD', // Currency of payment
          'value' => '1', // Amount of payment
      ),
      'order' => array(
          'id' => null, // Order No
          'desc' => 'Order Desc', // Order Description
          'extend_info' => array(
              'china_extra_trans_info' => array(
                  'business_type' => 'MEMBERSHIP', // Business Type of Order
              ),
          ),
      ),
      'payment_request_id' => null, // Cash payments could be null
      'settlement_strategy' => array(
          'currency' => 'USD', // Currency used for settlement
      ),
      'terminal_type' => TerminalType::WEB, // * Optional: WEB / WAP / APP
      'os_type' => null, // OS System Type
  ));
  header('Location: ' . $result->normalUrl); // Return URL of the alipay cashier
} catch (Exception $e) {
  echo $e->getMessage(); // Output Error
}

Online Payment - Authorization - Consult

API: ac/ams/authconsult
DEMO: auth/consult

use Mantoufan\tool\IdTool;
use Mantoufan\model\ScopeType;
use Mantoufan\model\TerminalType;
$auth_state = IdTool::CreateAuthState();
try {
    $result = $alipayGlobal->authConsult(array(
        'customer_belongs_to' => CustomerBelongsTo::ALIPAY_CN, // * Users pay with Alipay Chinese wallet,Optional: ALIPAY_CN / ALIPAY_HK / TRUEMONEY / TNG / GCASH / DANA / KAKAOPAY / EASYPAISA / BKASH
        'auth_client_id' => null, // Unique ID of the secondary merchant
        'auth_redirect_url' => '', // * URL that User is redirected to after User agrees to authorize
        'scopes' => array(ScopeType::AGREEMENT_PAY), // * Optional AGREEMENT_PAY / BASE_USER_INFO / USER_INFO / USER_LOGIN_ID / HASH_LOGIN_ID / SEND_OTP
        'auth_state' => $auth_state, // * It will be returned when User agrees to authorize needs to be guaranteed
        'terminal_type' => TerminalType::WEB, // * Optional: WEB / WAP / APP
        'os_type' => null, // OS System Type
    ));
    header('Location: ' . $result->normalUrl); // Return URL of User Authorization page With authCode
} catch (Exception $e) {
    echo $e->getMessage(); // Output Error
}

Online Payment - Authorization - ApplyToken - Using AuthCode

API: ac/ams/accesstokenapp
DEMO: auth/apply_token/auth_code

use Mantoufan\model\CustomerBelongsTo;
use Mantoufan\model\GrantType;
$auth_code = $_GET['authCode'] ?? '';
try {
    $result = $alipayGlobal->authApplyToken(array(
        'grant_type' => GrantType::AUTHORIZATION_CODE, // * Value should be AUTHORIZATION_CODE
        'customer_belongs_to' => CustomerBelongsTo::ALIPAY_CN, // * Users pay with Alipay Chinese wallet,Optional: ALIPAY_CN / ALIPAY_HK / TRUEMONEY / TNG / GCASH / DANA / KAKAOPAY / EASYPAISA / BKASH
        'auth_code' => $auth_code, // * AuthCode get from return URL of User Authorization page
        'refresh_token' => null, // Just leave null
    ));

    $access_token = $result->accessToken; // Access token is used for Aduto Debit
    $access_token_expiry_time = $result->accessTokenExpiryTime; // Access token expiry time
    $refresh_token = $result->refreshToken; // Refresh token is used for update access token
    $refresh_token_expiry_time = $result->refreshTokenExpiryTime; // Refresh token expiry time
    session_start(); // Start Session
    $_SESSION['access_token'] = $access_token; // Store Accesstoken in session
} catch (Exception $e) {
    echo $e->getMessage(); // Output Error
}

Online Payment - Authorization - ApplyToken - Using RefreshToken

API: ac/ams/accesstokenapp
DEMO: auth/apply_token/refresh_token

use Mantoufan\model\CustomerBelongsTo;
use Mantoufan\model\GrantType;
$refresh_token = $_GET['refreshToken'] ?? '';
try {
    $result = $alipayGlobal->authApplyToken(array(
        'grant_type' => GrantType::REFRESH_TOKEN, // * Value should be REFRESH_TOKEN
        'customer_belongs_to' => CustomerBelongsTo::ALIPAY_CN, // * Users pay with Alipay Chinese wallet,Optional: ALIPAY_CN / ALIPAY_HK / TRUEMONEY / TNG / GCASH / DANA / KAKAOPAY / EASYPAISA / BKASH
        'auth_code' => null, // Just leave null
        'refresh_token' => $refresh_token, // * RefreshToken get from authApplyToken Using AuthCode
    ));

    $access_token = $result->accessToken; // Access token is used for Aduto Debit
    $access_token_expiry_time = $result->accessTokenExpiryTime; // Access token expiry time
    $refresh_token = $result->refreshToken; // Refresh token is used for update access token
    $refresh_token_expiry_time = $result->refreshTokenExpiryTime; // Refresh token expiry time
    session_start(); // Start Session
    $_SESSION['access_token'] = $result->accessToken; // Store Accesstoken in session
} catch (Exception $e) {
    echo $e->getMessage(); // Output Error
}

Online payment - Payment - Pay (Auto Debit)

API: ac/ams/payment_agreement
DEMO: pay/agreement

try {
    session_start();
    $result = $alipayGlobal->payAgreement(array(
        'notify_url' => '', // Asynchronous callback Url
        'return_url' => '', // Synchronous callback Url
        'amount' => array(
            'currency' => 'USD', // Currency of payment
            'value' => '1', // Amount of payment
        ),
        'order' => array(
            'id' => null, // Order No
            'desc' => 'Order Desc', // Order Description
            'extend_info' => array(
                'china_extra_trans_info' => array(
                    'business_type' => 'MEMBERSHIP', // Business Type of Order
                ),
            ),
        ),
        'goods' => array(
            array(
                'id' => null, // Goods ID
                'name' => 'Goods Name', // Goods Name
                'category' => null, // Goods Category
                'brand' => null, // Goods Brand
                'unit_amount' => null, // Goods Charge Unit
                'quantity' => null, // Goods Quantity
                'sku_name' => null, // Goods SKU Name
            ),
        ),
        'merchant' => array( // Secondary merchant Info
            'MCC' => null,
            'name' => null,
            'display_name' => null,
            'address' => null,
            'register_date' => null,
            'store' => null,
            'type' => null,
        ),
        'buyer' => array( // Buyer Info
            'id' => null, // Buyer ID
            'name' => array(
                'first_name' => 'David', // * Buyer First Name
                'last_name' => 'Chen', // * Buyer Last Name
            ),
            'phone_no' => null, // Buyer Phone Number
            'email' => null, // Buyer Email
        ),
        'payment_request_id' => null, // Auto Debit payments could be null
        'payment_method' => array(
            'payment_method_type' => CustomerBelongsTo::ALIPAY_CN, // * Users pay with Alipay Chinese wallet,Optional: ALIPAY_CN / ALIPAY_HK / TRUEMONEY / TNG / GCASH / DANA / KAKAOPAY / EASYPAISA / BKASH
            'payment_method_id' => $_SESSION['access_token'], // * AccessToken returned by applyToken
        ),
        'settlement_strategy' => array(
            'currency' => 'USD', // Currency used for settlement
        ),
        'terminal_type' => TerminalType::WEB, // * Optional: WEB / WAP / APP
        'os_type' => null, // OS Type
    ));
    var_dump($result); // Output Result
} catch (Exception $e) {
    echo $e->getMessage(); // Output Error
}

Online payment - Payment - NotifyPayment

API: ac/ams/paymentrn_online
DEMO: notify

try {
    /* Get Asynchronous Payment Notifications */
    $notify = $alipayGlobal->getNotify();
    /* Default Value same as:
    $notify = $alipayGlobal->getNotify(array(
        'httpMethod' => $_SERVER['REQUEST_METHOD'],
        'path' => $_SERVER['REQUEST_URI'],
        'clientId' => $_SERVER['HTTP_CLIENT_ID'],
        'rsqTime' => $_SERVER['HTTP_REQUEST_TIME'],
        'rsqBody' => file_get_contents('php://input'),
        'signature' => $_SERVER['HTTP_SIGNATURE']
    ));*/
    /* Webman Example:
    $notify = $alipayGlobal->getNotify(array(
        'httpMethod' => $request->method(),
        'path' => $request->uri(),
        'clientId' => $request->header('client-id'),
        'rsqTime' => $request->header('request-time'),
        'rsqBody' => $request->rawBody(),
        'signature' => $request->header('signature')
    ));*/

    // Do something

    // Method 1: use header () and echo response
    $notify->sendNotifyResponseWithRSA(); // Tell Alipay Global the notice has been received and there is no need to send it again

    // Method 2: Or Get headers and body, process it by yourself
    $notifyResponseWithRSA =  $notify->getNotifyResponseWithRSA();
    // Webman Example:
    // response($notifyResponseWithRSA['body'], 200, $notifyResponseWithRSA['headers']);
} catch (Exception $e) {
    echo $e->getMessage(); // Output Error
}

Online Payment - Authorization - NotifyAuthorization

API: ac/ams/notifyauth
DEMO: notify/auth/auth_code

try {
    /* Get Asynchronous Payment Notifications */
    $notify = $alipayGlobal->getNotify();
    /* Default Value same as:
    $notify = $alipayGlobal->getNotify(array(
        'httpMethod' => $_SERVER['REQUEST_METHOD'],
        'path' => $_SERVER['REQUEST_URI'],
        'clientId' => $_SERVER['HTTP_CLIENT_ID'],
        'rsqTime' => $_SERVER['HTTP_REQUEST_TIME'],
        'rsqBody' => file_get_contents('php://input'),
        'signature' => $_SERVER['HTTP_SIGNATURE']
    ));*/
    /* Webman Example:
    $notify = $alipayGlobal->getNotify(array(
        'httpMethod' => $request->method(),
        'path' => $request->uri(),
        'clientId' => $request->header('client-id'),
        'rsqTime' => $request->header('request-time'),
        'rsqBody' => $request->rawBody(),
        'signature' => $request->header('signature')
    ));*/

    // Do something

    $rsqBody = $notify->getRsqBody(); // Get Response Body of Notification
    $authorization_notify_type = $reqBody->authorizationNotifyType; // Determine Notification Type
    if ($authorization_notify_type === 'AUTHCODE_CREATED') { // If Notification Type is sent AuthCode
        $_SESSION['auth_code'] = $reqBody->authCode; // Get AuthCode
    }

    // Method 1: use header () and echo response
    $notify->sendNotifyResponseWithRSA(); // Tell Alipay Global the notice has been received and there is no need to send it again

    // Method 2: Or Get headers and body, process it by yourself
    $notifyResponseWithRSA =  $notify->getNotifyResponseWithRSA();
    // Webman Example:
    // response($notifyResponseWithRSA['body'], 200, $notifyResponseWithRSA['headers']);
} catch (Exception $e) {
    echo $e->getMessage(); // Output Error
}

Online Payment - Refund - Refund

API: ac/ams/refund_online
DEMO: refund/refund_online

try {
    $result = $alipayGlobal->sendRefund(array(
        'paymentId' => '20181129190741010007000000XXXX', // Unique ID assigned by Alipay for the original payment to be refunded.
        'refundRequestId' => 'S7mMoYxQxWjJDWwm2NG4WxmNbM5z3GvSB6PEPvMeYP21PQUtrX9hXlgbQMajt2on', // Unique ID assigned by the merchant to identify a refund request.
        'refundAmount' => array(
            'currency' => 'USD', // Currency of refund
            'value' => '100', // Amount of refund
        )
    ));
    var_dump($result);
} catch (Exception $e) {
    echo $e->getMessage();
}

Return Url

DEMO: return

/** Return immediately after payment or authorization
 * After Payment, user will be redirected only
 * After Authorization, user will be redirected with authCode
 * Suggestion: The Return URL is only used as a reminder
 * It's beter to process business in asynchronous payment notification and asynchronous authorization notification
**/
echo 'Payment Or Authorization completed';

alipay-global-sdk-php's People

Contributors

listill avatar mantoufan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

alipay-global-sdk-php's Issues

Payment Notify Verify is 0

We use alipay global's public key:(sandbox)
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtOcJhqk3mKhcGC0ARNjdFoZtYGEhfcgrUEUe9CF+sDzIJZMMVypRY67GoDQEdZTmHBPnVtsBRKNGSq4/h8r4BZ3XNE81K8CqwX0YzwqEvd0qlhyn9KzGCQF3Ps9wQRkPKdFzvmYcrW4WXmMOVMDg+XxuzNpXygqpxOJ++7Dpi8E6Ste0/ZtrJ2ACLIZVKCh951Cko25ePd2QyJpXq1g2jyWMRQVIapPp+t+UHG/4affBYI5GNREsxcXukg+SeymMlR2TwZvbyGYMlEb34icznLeD4jdkXOnU3pmkxYg2FmVCg0YujqrUL6yjQ648WkGruKFAyMkXC9inj9eZJwn8eQIDAQAB

And the notify verification is always 0.
Could you help to figure out the verify testing use case and we can check if code is correct?

e.g.

<?php

function verify($httpMethod, $path, $clientId, $rspTime, $rspBody, $signature, $alipayPublicKey)
{
    $rspContent = genSignContent($httpMethod, $path, $clientId, $rspTime, $rspBody);
    return verifySignatureWithSHA256RSA($rspContent, $signature, $alipayPublicKey);
}

function genSignContent($httpMethod, $path, $clientId, $timeString, $content)
{
    $payload = $httpMethod . " " . $path . "\n" . $clientId . "." . $timeString . "." . $content;
    return $payload;
}
function verifySignatureWithSHA256RSA($rspContent, $rspSignValue, $alipayPublicKey)
{
    $pubKey = "-----BEGIN PUBLIC KEY-----\n" .
        wordwrap($alipayPublicKey, 64, "\n", true) .
        "\n-----END PUBLIC KEY-----";
    if (
        strstr($rspSignValue, "=")
        || strstr($rspSignValue, "+")
        || strstr($rspSignValue, "/")
        || $rspSignValue == base64_encode(base64_decode($rspSignValue))
    ) {
        $originalRspSignValue = base64_decode($rspSignValue);
    } else {
        $originalRspSignValue = base64_decode(urldecode($rspSignValue));
    }
    $verifyResult = openssl_verify($rspContent, $originalRspSignValue, $pubKey, OPENSSL_ALGO_SHA256);
    return $verifyResult;
}
$httpMethod = "POST";
$path = "";
$clientId = "SANDBOX_5Y606G2YJPQB00270";
$rspTime = "2022-04-26T04:39:22Z";

$signature = "bc6MuaBUCbIgxG6fbGh6MHJP%2FqiI6lrosdnN8mEEunDRR3k5j8cjRbGI8fAeE%2Bibhu%2FN4JxjGGCY7c%2B%2FTM8kUdv8nTdHU2MERsBn3mRcFe4eBW%2BxtFLL2brYaKSc%2Bb3mwIA0icHoUpwirVbfl9RrUviMsEJtSFW14rzKVjqBvwNo4iqzkh%2B2UIjzx%2FI7pbrSinZcJNZdjmMRRReQAMsYcrGGrzR%2BPtUjS%2FwNtA8NVHHk2LUeTuwtDVt%2F2ZxrsVm6C%2FufIZ3dz4yInSoR6fRms2%2FP67lb9PSTq0LGNM9EcXhtb3gCWmfdPPrUUuqxuBgDFno7%2F2%2BaPcht3GKP%2FPNrAg%3D%3D";
$alipayPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAi1ltikGrnsmknSD/OYNQSMw485C/OF7Y9MVxHIDkbIWZm8JC9cuhdZbduTmx2AKeDmkYK73dbF1xZnZQGd38sSKAkiWOSbz15a0bfd/XMlcx5ICqjkWi6gMWYOgUBp1RLuHvisjicwb4fBIN7IPySGMvSFFgPspUUc6gY3HKJgP59KAUJR1WA7B7tPw0C/xhcRFKln0nsU7wzk7R4HhYzKua0BxV6mYYDxGbVepH5tJ5ZzSNVR3IGJRQc6c7+gU1F6z5Jc3V4NT7EHOmu7T888A+Uhec+4XymTVNkRZ+u6ZEj03oMwtv7NcQf2z8Kcp1/VeyOg7toXoQjNtH2oEIWQIDAQAB";
$rspBody = '{
    "notifyType": "PAYMENT_RESULT",
    "result": {
        "resultCode": "SUCCESS",
        "resultStatus": "S",
        "resultMessage": "success"
    },
    "paymentRequestId": "20200101234567890444",
    "paymentId": "20200101234567890132",
    "paymentAmount": {
        "value": "8000",
        "currency": "EUR"
    },
    "actualPaymentAmount": {
        "value": "8000",
        "currency": "EUR"
    },
    "paymentCreateTime": "2020-01-01T12:01:00+08:30",
    "paymentTime": "2020-01-01T12:01:01+08:30"
}';
echo (int) verify($httpMethod, $path, $clientId, $rspTime, $rspBody, $signature, $alipayPublicKey);

the above data is from alipay global's inotify testing data.
All fields is copied at alipay's console except path field, according to the API document notify need to fill the path filed. Could you help me to check if path is needed and how to fill this field when we verify the notification from the payment transaction(async) .

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.