12/08/2018, 13:41

Tích hợp cổng thanh toán Paypal vào ứng dụng Android sử dụng PHP, MySQL (Phần 2)

Trong phần trước Tích hợp cổng thanh toán Paypal vào ứng dụng Android sử dụng PHP, MySQL (Phần 1) , chúng ta đã tích hợp PayPal phía máy chủ tức là tạo ra cơ sở dữ liệu mysql và viết các API PHP để tương tác với ứng dụng Android và PayPal API REST. Trong phần này chúng ta sẽ làm tiếp phần còn lại ...

Trong phần trước Tích hợp cổng thanh toán Paypal vào ứng dụng Android sử dụng PHP, MySQL (Phần 1) , chúng ta đã tích hợp PayPal phía máy chủ tức là tạo ra cơ sở dữ liệu mysql và viết các API PHP để tương tác với ứng dụng Android và PayPal API REST.

Trong phần này chúng ta sẽ làm tiếp phần còn lại đó là xây dựng ứng dụng Android và tích hợp cổng thanh toán PayPal. Sau đó chúng ta sẽ thực hiện một vài bài kiểm tra trong môi trường sandbox.

9. Tải về PayPal Android SDK

Cũng giống như PayPal PHP REST API SDK, PayPal cung cấp SDK cho nền tảng di động. Tải SDK PayPal Android và giải nén nó. Sau khi giải nén bạn sẽ thấy một ứng dụng mẫu, tài liệu và thư viện. Chúng ta sẽ libs. Nếu bạn muốn thử thanh toán với hình thức Future PaymentsProfile Sharing, bạn có thể tìm code hướng dẫn trong ứng dụng mẫu.

10. Tạo Android project

Bây giờ chúng ta sẽ cùng nhau xây dựng Android project

  1. Tạo một dự án mới trong Eclipse bằng cách vào File ⇒ New ⇒ Android Application Project và điền vào các thông tin cần thiết.

Tôi đã đặt tên dự án của tôi như PayPalClient và tên package là info.androidhive.paypalclient

  1. Bây giờ tôi tạo thêm hai package có tên là apphelper.

  2. Paste tất cả các nội dung của thư viện PayPal Android SDK của thư mục vào thư mục libs của dự án.

Dưới đây là cấu trúc dự án mà chúng ta sẽ tạo ra. Bạn cần phải có tất cả các file lib PayPal và các gói đặt như hình dưới đây.

project_struct

  1. Mở file colors.xmlres ⇒ value và thêm vào các định nghĩa màu mới
colors.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="btn_bg_checkout">#428bca</color>
    <color name="list_divider">#dedede</color>
    <color name="white">#ffffff</color>
    <color name="lbl_product_name">#333333</color>
    <color name="lbl_product_description">#444444</color>
    <color name="bg_msg_you">#5eb964</color>
    <color name="bg_msg_from">#e5e7eb</color>
    <color name="msg_border_color">#a1a1a1</color>
    <color name="bg_btn_join">#1e6258</color>
    <color name="bg_msg_input">#e8e8e8</color>
    <color name="text_msg_input">#626262</color>
    <color name="lblFromName">#777777</color>
</resources>

  1. Open strings.xmlres ⇒ value và thêm vào những chuỗi giá trị mới
strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">PalPal Client</string>
    <string name="checkout">Checkout</string>
    <string name="add_to_cart">Add to Cart</string>

</resources>

  1. Tôi đang sử dụng thư viện volley để thực hiện cuộc gọi API. Tải volley.jar và paste nó vào thư mục libs. (Nếu bạn là người mới dùng thư viện Volley, Hướng dẫn này sẽ đưa đến cho bạn một cái nhìn tốt về thư viện Volley).

  2. Tạo lớp có tên LruBitmapCache.java trong package helper. Mục đích của lớp học này để cache ảnh tải về.

LruBitmapCache.java
package info.androidhive.palpalclient.helper;

import com.android.volley.toolbox.ImageLoader.ImageCache;

import android.graphics.Bitmap;
import android.support.v4.util.LruCache;

public class LruBitmapCache extends LruCache<String, Bitmap> implements
        ImageCache {
    public static int getDefaultLruCacheSize() {
        final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
        final int cacheSize = maxMemory / 8;

        return cacheSize;
    }

    public LruBitmapCache() {
        this(getDefaultLruCacheSize());
    }

    public LruBitmapCache(int sizeInKiloBytes) {
        super(sizeInKiloBytes);
    }

    @Override
    protected int sizeOf(String key, Bitmap value) {
        return value.getRowBytes() * value.getHeight() / 1024;
    }

    @Override
    public Bitmap getBitmap(String url) {
        return get(url);
    }

    @Override
    public void putBitmap(String url, Bitmap bitmap) {
        put(url, bitmap);
    }
}

  1. Crete một lớp có tên AppController.java trong gói app. Đây là một lớp singleton được mở rộng từ lớp Application, lớp này sẽ được khởi chạy từ từ khi ứng dụng bắt đầu chạy. Tất cả việc khởi tạo các đối tượng volley sẽ được thực hiện ở đây.
AppController.java
package info.androidhive.palpalclient.app;

import info.androidhive.palpalclient.helper.LruBitmapCache;
import android.app.Application;
import android.text.TextUtils;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.Volley;

public class AppController extends Application {

    public static final String TAG = AppController.class.getSimpleName();

    private RequestQueue mRequestQueue;
    private ImageLoader mImageLoader;

    private static AppController mInstance;

    @Override
    public void onCreate() {
        super.onCreate();
        mInstance = this;
    }

    public static synchronized AppController getInstance() {
        return mInstance;
    }

    public RequestQueue getRequestQueue() {
        if (mRequestQueue == null) {
            mRequestQueue = Volley.newRequestQueue(getApplicationContext());
        }

        return mRequestQueue;
    }

    public ImageLoader getImageLoader() {
        getRequestQueue();
        if (mImageLoader == null) {
            mImageLoader = new ImageLoader(this.mRequestQueue,
                    new LruBitmapCache());
        }
        return this.mImageLoader;
    }

    public <T> void addToRequestQueue(Request<T> req, String tag) {
        // set the default tag if tag is empty
        req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
        getRequestQueue().add(req);
    }

    public <T> void addToRequestQueue(Request<T> req) {
        req.setTag(TAG);
        getRequestQueue().add(req);
    }

    public void cancelPendingRequests(Object tag) {
        if (mRequestQueue != null) {
            mRequestQueue.cancelAll(tag);
        }
    }
}

  1. Bây giờ chỉnh sửa AndroidManifest.xml theo chỉ dẫn ở dưới đây.

Kai báo AppController để trong thẻ <application> sử dụng android:name sở hữu tên.

Thêm các quyền CAMERA, VIBRATE, ACCESS_NETWORK_STATE, INTERNET.

Thêm các tính năng camera. Điều này là cần thiết khi người dùng muốn thanh toán bằng tính năng card.io**.

Thêm PayPalService

Thêm các PayPal SDK activities (PaymentActivity, LoginActivity, PaymentMethodActivity, PaymentConfirmActivity và CardIOActivity). Đây là những activity cần thiết để thực hiện thanh toán paypal.

Cuối cùng AndroidManifest.xml sẽ giống như dưới đây.

AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="info.androidhive.palpalclient"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="21" />

     
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.VIBRATE" />

    <uses-feature
        android:name="android.hardware.camera"
        android:required="false" />
    <uses-feature
        android:name="android.hardware.camera.autofocus"
        android:required="false" />

     
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:name="info.androidhive.palpalclient.app.AppController"
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name="info.androidhive.palpalclient.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service
            android:name="com.paypal.android.sdk.payments.PayPalService"
            android:exported="false" />

        <activity android:name="com.paypal.android.sdk.payments.PaymentActivity" />
        <activity android:name="com.paypal.android.sdk.payments.LoginActivity" />
        <activity android:name="com.paypal.android.sdk.payments.PaymentMethodActivity" />
        <activity android:name="com.paypal.android.sdk.payments.PaymentConfirmActivity" />
        <activity
            android:name="io.card.payment.CardIOActivity"
            android:configChanges="keyboardHidden|orientation" />
        <activity android:name="io.card.payment.DataEntryActivity" />
    </application>

</manifest>

  1. Tạo một lớp có tên Config.java trong gói app. Lớp này chứa tất cả các biến cấu hình như PayPal client id & secret, môi trường paypal và url endpoint để truy cập vào máy chủ mà chúng tôi xây dựng trong phần đầu tiên của loạt bài này.
Config.java
package info.androidhive.palpalclient.app;

import com.paypal.android.sdk.payments.PayPalConfiguration;
import com.paypal.android.sdk.payments.PayPalPayment;

public class Config {

    // PayPal app configuration
    public static final String PAYPAL_CLIENT_ID = "AbLgy0hRsq0PmoGK-ws2-jlBIeBVKUUU0xRjbfW1-GAckylz_TDNsh1cMrIiSksc2wpqYC2PisTrKhko";
    public static final String PAYPAL_CLIENT_SECRET = "";

    public static final String PAYPAL_ENVIRONMENT = PayPalConfiguration.ENVIRONMENT_SANDBOX;
    public static final String PAYMENT_INTENT = PayPalPayment.PAYMENT_INTENT_SALE;
    public static final String DEFAULT_CURRENCY = "USD";

    // PayPal server urls
    public static final String URL_PRODUCTS = "http://192.168.0.103/PayPalServer/v1/products";
    public static final String URL_VERIFY_PAYMENT = "http://192.168.0.103/PayPalServer/v1/verifyPayment";

}

  1. Tạo một lớp model có tên Product.java trong package helper. Lớp này sẽ được sử dụng trong khi phân tích các sản phẩm trả về nằm trong chuỗi json.
Product.java
package info.androidhive.palpalclient.helper;

import java.math.BigDecimal;

public class Product {
    private String id, name, description, image, sku;
    private BigDecimal price;

    public Product() {

    }

    public Product(String id, String name, String description, String image,
            BigDecimal price, String sku) {
        this.id = id;
        this.name = name;
        this.description = description;
        this.image = image;
        this.price = price;
        this.sku = sku;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getImage() {
        return image;
    }

    public void setImage(String image) {
        this.image = image;
    }

    public BigDecimal getPrice() {
        return price;
    }

    public void setPrice(BigDecimal price) {
        this.price = price;
    }

    public String getSku() {
        return sku;
    }

    public void setSku(String sku) {
        this.sku = sku;
    }

}

  1. Theo res ⇒ layout, tạo ra một tập tin có tên list_item_product.xml. File giao diện này sẽ vẽ một row trong danh sách các sản phẩm. Cách bố trí này có chứa hình ảnh sản phẩm ở bên trái là các chi tiết như tên sản phẩm, mô tả, giá cả ở bên phải.
list_item_product.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_awidth="match_parent"
    android:layout_height="match_parent"
    android:background="@color/white"
    android:paddingBottom="10dp" >

    <com.android.volley.toolbox.NetworkImageView
        android:id="@+id/productImage"
        android:layout_awidth="100dp"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_margin="8dp"
        android:scaleType="fitCenter" >
    </com.android.volley.toolbox.NetworkImageView>

    <TextView
        android:id="@+id/productName"
        android:layout_awidth="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/productImage"
        android:padding="5dp"
        android:textColor="@color/lbl_product_name"
        android:textSize="16dp"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/productDescription"
        android:layout_awidth="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/productName"
        android:layout_toRightOf="@id/productImage"
        android:padding="5dp"
        android:textColor="@color/lbl_product_description" />

    <TextView
        android:id="@+id/productPrice"
        android:layout_awidth="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/productDescription"
        android:layout_toRightOf="@id/productImage"
        android:padding="5dp"
        android:textColor="@color/lbl_product_description" />

    <
            
            
            
         
0