Thanh toán trực tuyến Stripe bằng Php

Ngày nay, việc phát triển thương mại điện tử rất mạnh mẽ, giờ ngày càng nhiều trang thương mại điện tử phát triển rất mạnh mẽ, đem lại sự tiện lợi cho nhiều người dùng. Trong các sản phẩm về thương mại điện tử, 1 trong các vấn đề quan trọng nhất đó chính là phương thức thanh toán. Một sản phẩm thương mại điện tử nếu chỉ có thanh toán bằng tiền mặt có lẽ không đem lại sức mạnh to lớn như hiện tại, ngoài ra cần có phương thức thanh toán trực tuyến. Một trong các phương thức thanh toán online trực tuyến đó chính là thanh toán bằng thẻ quốc tế VISA, Master. Vậy làm sao để thực hiện thanh toán bằng các thẻ quốc tế, trong bài này tôi giới thiệu các bạn 1 trong nhiều cách đó là sử dụng qua trung gian Stripe.

Đăng ký và tải thư viện

Để sử dụng thanh toán thông qua bên thứ 3 là stripe bạn cần phải đăng ký tài khoản, sau khi đăng ký tài khoản thì có thể vào API để có thể lấy key cho việc sử dụng sắp tới. Sau khi đăng ký xong bạn có thể đăng nhập luôn nhưng vẫn cần thực hiện 1 bước xác thực trong email nữa. Chúng ta có thể lấy thư viện Stripe cho Php bằng cách down về hoặc qua composer như sau:

{
    "name": "framgia/payment-php",
    "authors": [
        {
            "name": "Huy nguyen",
            "email": "[email protected]"
        }
    ],
    "require": {
        "stripe/stripe-php": "4.10.0"
    }
}

Trong quá trình cài đặt có thể bị thiếu ext-curl, ext-mbstring, ext-json. Để khắc phục lỗi này các bạn chỉ cần cài thêm

sudo apt-get install php-curl php-mbstring php-json 

Sau cùng chúng ta lấy thư viện Stripe về bằng lệnh

composer install

Là có thể cài đặt thành công, giờ chúng ta tiến hành thử thanh toán thôi

Thực hiện thanh toán với Stripe

Để làm việc với Stripe ta cần gọi đến thư viện Stripe và thư viện Charge . Vậy ta làm như sau để gọi đến thư viện Stripe:

require __DIR__ . '/vendor/autoload.php';
use Stripe\Stripe;
use Stripe\Charge;

Như đã nói ở trên, chúng ta có thể lấy token sau khi đăng nhập xong, vậy để kiểm tra thử kết nối đến Stripe ta làm như sau:

<?php
require __DIR__ . '/vendor/autoload.php';
use Stripe\Stripe;
use Stripe\Charge;

Stripe::setApiKey('***');
$myCard = array('number' => '4242424242424242', 'exp_month' => 8, 'exp_year' => 2018);
$charge = Charge::create(array('card' => $myCard, 'amount' => 2000, 'currency' => 'usd'));
echo $charge;

Ở đây chúng ta có thể thấy card ở đây number là 4242424242424242, Các bạn yên tâm, đây không phải thẻ của mình đâu (hoho). Thực sự đây là mã thẻ mà để Stripe hiểu rằng chúng ta đang test thử. Do vậy các bạn không phải lo lắng về việc mất tiền thật. Và kết quả chúng ta nhận được sẽ là

Stripe\Charge JSON: { "id": "ch_1AOVKWKhqSpOPfoCu6wyVfQN", "object": "charge", "amount": 2000, "amount_refunded": 0, "application": null, "application_fee": null, "balance_transaction": "txn_1AOVKWKhqSpOPfoCUAYJyl5T", "captured": true, "created": 1495993048, "currency": "usd", "customer": null, "description": null, "destination": null, "dispute": null, "failure_code": null, "failure_message": null, "fraud_details": [], "invoice": null, "livemode": false, "metadata": [], "on_behalf_of": null, "order": null, "outcome": { "network_status": "approved_by_network", "reason": null, "risk_level": "normal", "seller_message": "Payment complete.", "type": "authorized" }, "paid": true, "receipt_email": null, "receipt_number": null, "refunded": false, "refunds": { "object": "list", "data": [], "has_more": false, "total_count": 0, "url": "\/v1\/charges\/ch_1AOVKWKhqSpOPfoCu6wyVfQN\/refunds" }, "review": null, "shipping": null, "source": { "id": "card_1AOVKWKhqSpOPfoClGFydZoZ", "object": "card", "address_city": null, "address_country": null, "address_line1": null, "address_line1_check": null, "address_line2": null, "address_state": null, "address_zip": null, "address_zip_check": null, "brand": "Visa", "country": "US", "customer": null, "cvc_check": null, "dynamic_last4": null, "exp_month": 8, "exp_year": 2018, "fingerprint": "7lLFoOuxY8Knmd0D", "funding": "credit", "last4": "4242", "metadata": [], "name": null, "tokenization_method": null }, "source_transfer": null, "statement_descriptor": null, "status": "succeeded", "transfer_group": null }

Wow, vậy là đã kết nối thành công, và khi đó chúng ta có thể vào bên trang Stripe để kiểm tra kết quả bằng cách vào xem Payment và kết quả chúng ta nhận được trên site đó là: Vậy làm sao chúng ta biết giao dịch vừa rồi đã thành công, các bạn có thể để ý trả về sẽ có id, ở đây là ch_1AOVKWKhqSpOPfoCu6wyVfQN và trong danh sách payment ta cũng có id này. Như vậy việc thanh toán vừa rồi đã thành công. Vậy để cho hoàn thiện, chúng ta sẽ chỉnh sửa 1 chút, đó là như sau:

<?php
require __DIR__ . '/vendor/autoload.php';
use Stripe\Stripe;
use Stripe\Charge;

if (isset($_POST['card_number']) ) {
    Stripe::setApiKey('***');
    $myCard = array('number' => $_POST['card_number'], 'exp_month' => $_POST['exp_month'], 'exp_year' => $_POST['exp_year']);
    $charge = Charge::create(array('card' => $myCard, 'amount' => $_POST['amount'], 'currency' => 'usd'));
    echo $charge;
} else {
   ?>
    <h3>Thanh toán điện tử với Stripe - Framgia</h3>
    <form action="" method="post">
        <div>
            <label>Số thẻ</label>
            <input name="card_number" type="text">
        </div>
        <div>
            <label>Tháng kết thúc</label>
            <input name="exp_month" type="text">
        </div>
        <div>
            <label>Năm kết thúc</label>
            <input name="exp_year" type="text">
        </div>
        <div>
            <label>Số tiền</label>
            <input name="amount" type="text">
        </div>
        <div>
            <input type="submit" value="Thanh toán">
        </div>
    </form>
<?php
}

Và trong quá trình làm, tôi có thử nhập sai khác thì nó ra thông báo 500. Vậy để hiển thị thông báo lỗi thì ta cần dùng hàm để bắt các sự kiện lỗi. Vậy code hoàn thiện sẽ như sau

<?php
require __DIR__ . '/vendor/autoload.php';
use Stripe\Stripe;
use Stripe\Charge;

if (isset($_POST['card_number']) ) {
    try {
        Stripe::setApiKey('***');
        $myCard = array('number' => $_POST['card_number'], 'exp_month' => $_POST['exp_month'], 'exp_year' => $_POST['exp_year']);
        $charge = Charge::create(array('card' => $myCard, 'amount' => $_POST['amount'], 'currency' => 'usd'));
        echo $charge;
        
    } catch(\Stripe\Error\Card $e) {
      // Since it's a decline, \Stripe\Error\Card will be caught
      $body = $e->getJsonBody();
      $err  = $body['error'];

      print('Status is:' . $e->getHttpStatus() . "\n");
      print('Type is:' . $err['type'] . "\n");
      print('Code is:' . $err['code'] . "\n");
      // param is '' in this case
      print('Param is:' . $err['param'] . "\n");
      print('Message is:' . $err['message'] . "\n");
    } catch (\Stripe\Error\RateLimit $e) {
      // Too many requests made to the API too quickly
    } catch (\Stripe\Error\InvalidRequest $e) {
      // Invalid parameters were supplied to Stripe's API
    } catch (\Stripe\Error\Authentication $e) {
      // Authentication with Stripe's API failed
      // (maybe you changed API keys recently)
    } catch (\Stripe\Error\ApiConnection $e) {
      // Network communication with Stripe failed
    } catch (\Stripe\Error\Base $e) {
      // Display a very generic error to the user, and maybe send
      // yourself an email
    } catch (Exception $e) {
      // Something else happened, completely unrelated to Stripe
    }
} else {
   ?>
    <h3>Thanh toán điện tử với Stripe - Framgia</h3>
    <form action="" method="post">
        <div>
            <label>Số thẻ</label>
            <input name="card_number" type="text">
        </div>
        <div>
            <label>Tháng kết thúc</label>
            <input name="exp_month" type="text">
        </div>
        <div>
            <label>Năm kết thúc</label>
            <input name="exp_year" type="text">
        </div>
        <div>
            <label>Số tiền</label>
            <input name="amount" type="text">
        </div>
        <div>
            <input type="submit" value="Thanh toán">
        </div>
    </form>
<?php
}

Vậy là chúng ta đã xử lý thành công về việc thanh toán điện tử bằng cách dùng thẻ quốc tế thông qua Stripe.

Kết luận

Trong bài viết này tôi chỉ đi sơ qua về cách sử dụng khá là đơn giản và tiện dụng. Tất nhiên khi thực hiện thanh toán thì số tiền thực lĩnh thường sẽ nhỏ hơn và tùy thuộc vào tài khoản mà bạn đăng ký. Stripe hỗ trợ rất nhiều các ngôn ngữ lập trình khác nhau như Php, Ruby, Python, curl, java,... như vậy rất tiện cho việc sử dụng cho các nhà phát triên.