Android access to Alipay payment implementation

Keywords: Android Java SDK Mobile

Next, android access WeChat payment article, this we take you to access Alipay payment services.

brief introduction

The first thing to explain is that personal feeling is much easier to access Alipay than WeChat, so students should not be nervous.

Of course, it's still the old rule. I'll stick it up for sure Official website address , because these services are updated every day, and my article is to teach you methods, and let you not follow the gourd


 

There are two ways to enter the app payment document. One is directly in the following open business


 

The other is to scroll to the service access column through the document center of the navigation bar above to see the mobile payment


 

It can also be opened directly This address , there are still a lot of documents. You can pay attention to the items I checked


 

First of all, I also want to explain that individuals are not allowed to apply, only enterprises, so some of the data used in my demo is also in the demo

This is the interactive process Official documents You can click in if you need more details

Run Demo

We are here Download address of official demo


 

You can see that there are two. Just choose what you need. After downloading and decompressing, import eclipse directly and configure some parameters to run to see the effect

Import jar

Copy alipaySdk-20160223.jar in demo to libs of our project, and add it to dependency

To configure

Jurisdiction

ses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

activity

<activity
    android:name="com.alipay.sdk.app.H5PayActivity"
    android:configChanges="orientation|keyboardHidden|navigation"
    android:exported="false"
    android:screenOrientation="behind">
</activity>
<activity
    android:name="com.alipay.sdk.auth.AuthActivity"
    android:configChanges="orientation|keyboardHidden|navigation"
    android:exported="false"
    android:screenOrientation="behind">
</activity>

Order data generation

This step can be completed on the server or locally

String orderInfo = getOrderInfo("Tested products", "Detailed description of the test product", "0.01");
 
/**
 * Special attention: the signature logic here needs to be placed on the server side. Do not disclose the private key in the code!
 */
String sign = sign(orderInfo);
try {
    /**
     * Just URL code sign
     */
    sign = URLEncoder.encode(sign, "UTF-8");
} catch (UnsupportedEncodingException e) {
    e.printStackTrace();
}
 
/**
 * Complete order information conforming to Alipay parameter specification
 */
final String payInfo = orderInfo + "&sign=\"" + sign + "\"&" + getSignType();
 
Runnable payRunnable = new Runnable() {
 
    @Override
    public void run() {
        // structure PayTask object
        PayTask alipay = new PayTask(MainActivity.this);
        // Call the payment interface to get the payment result
        String result = alipay.pay(payInfo, true);
 
        Message msg = new Message();
        msg.what = SDK_PAY_FLAG;
        msg.obj = result;
        mHandler.sendMessage(msg);
    }
};
 
// Must be called asynchronously
Thread payThread = new Thread(payRunnable);
payThread.start();

Process payment results

@SuppressLint("HandlerLeak")
private Handler mHandler = new Handler() {
    @SuppressWarnings("unused")
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case SDK_PAY_FLAG: {
                PayResult payResult = new PayResult((String) msg.obj);
                /**
                 * The returned synchronization results must be placed on the server for verification (for the verification rules, see https://doc.open.alipay.com/doc2/
                 * detail.htm?spm=0.0.0.0.xdvAU6&treeId=59&articleId=103665&
                 * docType=1) Advise merchants to rely on asynchronous notification
                 */
                String resultInfo = payResult.getResult();// Synchronization returns information to be verified
 
                String resultStatus = payResult.getResultStatus();
                // judge resultStatus If it is "9000", the payment is successful. For the specific status code, please refer to the interface document
                if (TextUtils.equals(resultStatus, "9000")) {
                    Toast.makeText(MainActivity.this, "Payment successful", Toast.LENGTH_SHORT).show();
                } else {
                    // judge resultStatus For non"9000"The payment may fail
                    // "8000"It means that the payment result is still waiting for confirmation due to payment channel or system reasons. The final transaction success depends on asynchronous notification of the server (small probability state)
                    if (TextUtils.equals(resultStatus, "8000")) {
                        Toast.makeText(MainActivity.this, "Payment result is being confirmed", Toast.LENGTH_SHORT).show();
 
                    } else {
                        // Other values can be judged as payment failure, including the user cancels the payment actively or the system returns an error
                        Toast.makeText(MainActivity.this, "Payment failure", Toast.LENGTH_SHORT).show();
 
                    }
                }
                break;
            }
            default:
                break;
        }
    }
 
};

The payment is successful. It only prompts the user, and has to confirm whether it is paying from the server. I only write the local here. If the server is implemented the same, you send the code directly to the backend (if the back end is Java Development), we can see that we have successfully switched the Alipay service.


 

Full code:

package cn.woblog.testalipay;
 
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.View;
import android.widget.Toast;
 
import com.alipay.sdk.app.PayTask;
 
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Random;
 
import cn.woblog.testalipay.domain.PayResult;
import cn.woblog.testalipay.util.SignUtils;
 
public class MainActivity extends AppCompatActivity {
    public static final String PARTNER = "";
 
    // Merchant Collection account
    public static final String SELLER = "";
 
    // Merchant private key, pkcs8 format
    public static final String RSA_PRIVATE = "";
 
    private static final int SDK_PAY_FLAG = 1;
 
    @SuppressLint("HandlerLeak")
    private Handler mHandler = new Handler() {
        @SuppressWarnings("unused")
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case SDK_PAY_FLAG: {
                    PayResult payResult = new PayResult((String) msg.obj);
                    /**
                     * The returned synchronization results must be placed on the server for verification (for the verification rules, see https://doc.open.alipay.com/doc2/
                     * detail.htm?spm=0.0.0.0.xdvAU6&treeId=59&articleId=103665&
                     * docType=1) Advise merchants to rely on asynchronous notification
                     */
                    String resultInfo = payResult.getResult();// Synchronization returns information to be verified
 
                    String resultStatus = payResult.getResultStatus();
                    // judge resultStatus If it is "9000", the payment is successful. For the specific status code, please refer to the interface document
                    if (TextUtils.equals(resultStatus, "9000")) {
                        Toast.makeText(MainActivity.this, "Payment successful", Toast.LENGTH_SHORT).show();
                    } else {
                        // judge resultStatus For non"9000"The payment may fail
                        // "8000"It means that the payment result is still waiting for confirmation due to payment channel or system reasons. The final transaction success depends on asynchronous notification of the server (small probability state)
                        if (TextUtils.equals(resultStatus, "8000")) {
                            Toast.makeText(MainActivity.this, "Payment result is being confirmed", Toast.LENGTH_SHORT).show();
 
                        } else {
                            // Other values can be judged as payment failure, including the user cancels the payment actively or the system returns an error
                            Toast.makeText(MainActivity.this, "Payment failure", Toast.LENGTH_SHORT).show();
 
                        }
                    }
                    break;
                }
                default:
                    break;
            }
        }
 
    };
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
 
    public void testAlipay(View view) {
        if (TextUtils.isEmpty(PARTNER) || TextUtils.isEmpty(RSA_PRIVATE) || TextUtils.isEmpty(SELLER)) {
            new AlertDialog.Builder(this).setTitle("warning").setMessage("Configuration required PARTNER | RSA_PRIVATE| SELLER")
                    .setPositiveButton("Determine", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialoginterface, int i) {
                            //
                            finish();
                        }
                    }).show();
            return;
        }
 
        String orderInfo = getOrderInfo("Tested products", "Detailed description of the test product", "0.01");
 
/**
 * Special attention: the signature logic here needs to be placed on the server side. Do not disclose the private key in the code!
 */
        String sign = sign(orderInfo);
        try {
            /**
             * Just URL code sign
             */
            sign = URLEncoder.encode(sign, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
 
/**
 * Complete order information conforming to Alipay parameter specification
 */
        final String payInfo = orderInfo + "&sign=\"" + sign + "\"&" + getSignType();
 
        Runnable payRunnable = new Runnable() {
 
            @Override
            public void run() {
                // structure PayTask object
                PayTask alipay = new PayTask(MainActivity.this);
                // Call the payment interface to get the payment result
                String result = alipay.pay(payInfo, true);
 
                Message msg = new Message();
                msg.what = SDK_PAY_FLAG;
                msg.obj = result;
                mHandler.sendMessage(msg);
            }
        };
 
// Must be called asynchronously
        Thread payThread = new Thread(payRunnable);
        payThread.start();
    }
 
 
    /**
     * create the order info. Create order information
     */
    private String getOrderInfo(String subject, String body, String price) {
 
        // Identity of signing partner ID
        String orderInfo = "partner=" + "\"" + PARTNER + "\"";
 
        // Signed seller Alipay account
        orderInfo += "&seller_id=" + "\"" + SELLER + "\"";
 
        // Unique order number of merchant website
        orderInfo += "&out_trade_no=" + "\"" + getOutTradeNo() + "\"";
 
        // Commodity name
        orderInfo += "&subject=" + "\"" + subject + "\"";
 
        // Product details
        orderInfo += "&body=" + "\"" + body + "\"";
 
        // Commodity amount
        orderInfo += "&total_fee=" + "\"" + price + "\"";
 
        // Server asynchronous notification page path
        orderInfo += "&notify_url=" + "\"" + "http://notify.msp.hk/notify.htm" + "\"";
 
        // Service interface name, fixed value
        orderInfo += "&service=\"mobile.securitypay.pay\"";
 
        // Payment type, fixed value
        orderInfo += "&payment_type=\"1\"";
 
        // Parameter code, fixed value
        orderInfo += "&_input_charset=\"utf-8\"";
 
        // Set the time-out for outstanding transactions
        // The default is 30 minutes. Once the timeout occurs, the transaction will be automatically closed.
        // Value range: 1 m~15d. 
        // m-minute, h-Hours, d-Days, 1 c-Same day (close at 0:00 whenever a transaction is created).
        // Decimal point is not allowed for this parameter value, such as 1.5h,Can be converted to 90 m. 
        orderInfo += "&it_b_pay=\"30m\"";
 
        // extern_token Obtained by express login authorization alipay_open_id,With this parameter, the user will use the authorized account for payment
        // orderInfo += "&extern_token=" + "\"" + extern_token + "\"";
 
        // After processing Alipay's request, the current page skips to the path specified by the merchant.
        orderInfo += "&return_url=\"m.alipay.com\"";
 
        // To call bank card payment, you need to configure this parameter, participate in signature and fixed value (you need to sign the wireless bank card express payment to use it)
        // orderInfo += "&paymethod=\"expressGateway\"";
 
        return orderInfo;
    }
 
    /**
     * sign the order info. Sign order information
     *
     * @param content Order information to be signed
     */
    private String sign(String content) {
        return SignUtils.sign(content, RSA_PRIVATE);
    }
 
    /**
     * get the sign type we use. Get signature method
     */
    private String getSignType() {
        return "sign_type=\"RSA\"";
    }
 
    /**
     * get the out_trade_no for an order. Generate the merchant order number, which should be unique at the merchant end (customizable format specification)
     */
    private String getOutTradeNo() {
        SimpleDateFormat format = new SimpleDateFormat("MMddHHmmss", Locale.getDefault());
        Date date = new Date();
        String key = format.format(date);
 
        Random r = new Random();
        key = key + r.nextInt();
        key = key.substring(0, 15);
        return key;
    }
 
}

If you want to test the demo, replace

The value applied for by PARTNER, SELLER, RSA_PRIVATE in MainActivity

 

Posted by mattvenables on Fri, 24 Apr 2020 10:57:53 -0700