Android Edition - Wechat APP Payment

Keywords: Android git github SDK

Welcome to leave a message and forward it.
The first address of the article is: http://www.jianshu.com/p/febf7c2eea82 
WeChat Quick Development Series (Wechat Payment, Authorized Access to User Information, etc.) click here

Catalogue
1. Registration Account, Developer Certification
2. Adding applications
3. Application for Wechat Payment
4. Introduction to the steps of technology development function realization
5. Code examples

Server source address: http://git.oschina.net/javen205/weixin_guide 
Client source address: https://github.com/Javen205/JPay

Wechat APP Payment Access Business Service Center Official Introduction Documents

1. Registration Account and Developer Certification

stay Open Platform Direct registration, registration mailbox can not be the same number as other products of Wechat.

Comparing pitfalls are that the payment in Wechat Public Number (Wechat Payment, Credit Card, Public Number Payment, wap Payment) and Wechat app Payment need to be certified by Wechat instead of using a Wechat Business Platform (which requires two certifications).

Wechat certification takes a relatively short time (after all, 300 oceans) and you are usually contacted to check the company's information within a working day.

After the certification of Wechat (developer qualification certification) is passed, the application can be added to the open platform (this needs to be audited), and the application can be applied for payment by Wechat (also need to be audited).

2. Adding Applications

This is relatively simple, follow the prompt operation on the line above.

The application package name is defined only, and the application signature can be generated using the signature generation tool of the resource download center. Be sure to remember the package name and the password for signing the keystore file. If the package name or signature file is not packaged properly, Wechat will not be able to pay for it.

3. Application for Wechat Payment

If the application is approved (one working day), you can apply for Wechat payment directly (within 7 working days).

After the approval of the audit, the mail will be received, which contains the login account, password, business number and some instructions for the operation of the login business platform. The signature of the prepaid order generated by the server requires a key setting method. Refer here.

4. Realization of Technology Development Function

Introduction to Wechat APP Payment[ File
Description of development steps of APP end[ File]

Here is the main chat Android Wechat payment mainly includes the following steps.
1. The merchant server generates orders and prepaid orders on the Wechat platform.
2. Client calls up Wechat Payment to make payment.
3. Client callback payment results
4. Server receives payment notification

1. Merchant Service Generates Orders and Prepaid Orders on Wechat Platform

The server needs to generate payment order and call it again before the payment of Wechat is invoked.[ Unified Order API ] Generate prepayId for prepaid order and regenerate signature sign[ Call-up Payment API]

The above two steps are suggested to be completed on the server side and on the client side.( android ) Obtain the corresponding parameters through the interface.

2. Client calls up Wechat Payment for payment

Wake up Wechat Payment via the jar provided by Wechat

3. Client callback payment results

Referring to Wechat SDK Sample, WXPayEntryActivity class is implemented in net.sourceforge.simcpux.wxapi package path. [Inconsistent package name or class name will cause callback]
Chestnut Explanation: Read this sentence several times carefully and feel that it is a pit with ambiguity. test It never calls back. The consciousness he wants to say here is as follows:
For example, if you apply for an application package named javen.com, the callback WXPayEntry Activity class must be placed under the package of javen.com.wxapi

4. Server receives payment notification

Notification of Payment Result[ Official Documents]

Code Implementation Reference Open Source Project[ click here]

5. Code examples

Server Code: Generate Weichat prepaid order according to merchant order and return the parameters needed to arouse Weichat payment. The parameters in Demo are fixed for reference only.

This project is open source[ click here ] If it helps you, please click Start to tell me hahaha. The following code corresponds to the directory at com.javen.weixin.controller.WeixinPayController. Java in

/**
     * Wechat APP Payment
     */
    public void appPay(){
        //Do not set authorized directory domain name
        //Unified single address https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_1#
        Map<String, String> params = new HashMap<String, String>();
        params.put("appid", appid);
        params.put("mch_id", partner);
        params.put("nonce_str", System.currentTimeMillis() / 1000 + "");
        params.put("body", "Javen The rapid development of Wechat Public Signal");
        String out_trade_no=System.currentTimeMillis()+"";
        params.put("attach", "custom json");
        params.put("out_trade_no", out_trade_no);
        int price=10000;
        params.put("total_fee", price+"");

        String ip = IpKit.getRealIp(getRequest());
        if (StrKit.isBlank(ip)) {
            ip = "127.0.0.1";
        }

        params.put("spbill_create_ip", ip);
        params.put("notify_url", notify_url);
        params.put("trade_type", "APP");

        String sign = PaymentKit.createSign(params, paternerKey);
        params.put("sign", sign);

        String xmlResult = PaymentApi.pushOrder(params);

System.out.println(xmlResult);
        Map<String, String> result = PaymentKit.xmlToMap(xmlResult);

        String return_code = result.get("return_code");
        String return_msg = result.get("return_msg");
        if (StrKit.isBlank(return_code) || !"SUCCESS".equals(return_code)) {
            ajax.addError(return_msg);
            renderJson(ajax);
            return;
        }
        String result_code = result.get("result_code");
        if (StrKit.isBlank(result_code) || !"SUCCESS".equals(result_code)) {
            ajax.addError(return_msg);
            renderJson(ajax);
            return;
        }
        // The following fields are returned when both return_code and result_code are SUCCESS
        String prepay_id = result.get("prepay_id");
        //Payment parameter https://pay for encapsulation and invocation of wechat.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_12
        Map<String, String> packageParams = new HashMap<String, String>();
        packageParams.put("appid", appid);
        packageParams.put("partnerid", partner);
        packageParams.put("prepayid", prepay_id);
        packageParams.put("package", "Sign=WXPay");
        packageParams.put("noncestr", System.currentTimeMillis() + "");
        packageParams.put("timestamp", System.currentTimeMillis() / 1000 + "");
        String packageSign = PaymentKit.createSign(packageParams, paternerKey);
        packageParams.put("sign", packageSign);

        String jsonStr = JsonUtils.toJson(packageParams);
System.out.println("Latest Return apk Parameters:"+jsonStr);
        renderJson(jsonStr);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
Client Code Implementation

Using the singleton mode to unify the entrance, the first step is to determine whether the Wechat client is installed or not, and if there is installation, then get the parameters of the payment from the merchant server.

public class IPay {
    private static  IPay mIPay;
    private Context mContext;

    private IPay(Context context) {
        mContext = context;
    }

    public static IPay getIntance(Context context){
        if (mIPay == null) {
            synchronized(IPay.class){
                if (mIPay == null) {
                    mIPay = new IPay(context);
                }
            }
        }
        return mIPay;
    }

    //Payment Result Callback
    public interface IPayListener{
        void onPay(int code);
    }

    public void toTestPay(Order order,IPayListener listener){
        if (order != null) {
            if (IPayLogic.getIntance(mContext.getApplicationContext()).isWeixinAvilible()) {
                Constants.payListener = listener;
                new TestPayPrepay(mContext).execute();
            }else {
                Toast.makeText(mContext, "No Wechat Installed", Toast.LENGTH_LONG).show();
            }
        }else {
            Toast.makeText(mContext, "Parametric anomaly order is null", Toast.LENGTH_LONG).show();
        }
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

Setting up Weichat Payment, Obtaining Weichat Payment Parameters and Judging whether Weichat Installation Logic Realization

public class IPayLogic {
    private static  IPayLogic mIPayLogic;
    private Context mContext;

    private IPayLogic(Context context) {
        mContext = context;
    }

    public static IPayLogic getIntance(Context context){
        if (mIPayLogic == null) {
            synchronized(IPayLogic.class){
                if (mIPayLogic == null) {
                    mIPayLogic = new IPayLogic(context);
                }
            }
        }
        return mIPayLogic;
    }

    //test
    public String testPay(){
        return HttpKit.get(Constants.TESTPAY_URL);
    }

    /**
     * Payment mobilization
     * @param appId
     * @param partnerId
     * @param prepayId
     * @param nonceStr
     * @param timeStamp
     * @param sign
     */
    public void startWXPay(String appId,String partnerId,String prepayId,
            String nonceStr,String timeStamp,String sign){

        IWXAPI api= WXAPIFactory.createWXAPI(mContext, null);
        api.registerApp(appId);

        boolean isPaySupported = api.getWXAppSupportAPI() >= Build.PAY_SUPPORTED_SDK_INT;
        if (!isPaySupported) {
            Toast.makeText(mContext, "Please update the Wechat Client", Toast.LENGTH_SHORT).show();
            return;
        }

        PayReq request = new PayReq();
        request.appId = appId;
        request.partnerId = partnerId;
        request.prepayId= prepayId;
        request.packageValue = "Sign=WXPay";
        request.nonceStr=nonceStr;
        request.timeStamp= timeStamp;
        request.sign= sign;
        api.sendReq(request);
    }


    /**
     * Judging whether Wechat is installed or not
     * @param context
     * @return
     */
     public  boolean isWeixinAvilible() {
            final PackageManager packageManager = mContext.getPackageManager();// Get package manager
            List<PackageInfo> pinfo = packageManager.getInstalledPackages(0);// Get package information for all installed programs
            if (pinfo != null) {
                for (int i = 0; i < pinfo.size(); i++) {
                    String pn = pinfo.get(i).packageName;
                    if (pn.equals("com.tencent.mm")) {
                        return true;
                    }
                }
            }
            return false;
        }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79

HttpKit MD5 Tool Class

/**
 * HttpKit
 */
public class HttpKit {

    private HttpKit() {}

    /**
     * https Domain name verification
     */
    private class TrustAnyHostnameVerifier implements HostnameVerifier {
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    }

    /**
     * https Certificate Management
     */
    private class TrustAnyTrustManager implements X509TrustManager {
        public X509Certificate[] getAcceptedIssuers() {
            return null;  
        }
        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }
        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }
    }

    private static final String GET  = "GET";
    private static final String POST = "POST";
    private static String CHARSET = "UTF-8";

    private static final SSLSocketFactory sslSocketFactory = initSSLSocketFactory();
    private static final TrustAnyHostnameVerifier trustAnyHostnameVerifier = new HttpKit().new TrustAnyHostnameVerifier();

    private static SSLSocketFactory initSSLSocketFactory() {
        try {
            TrustManager[] tm = {new HttpKit().new TrustAnyTrustManager() };
            SSLContext sslContext = SSLContext.getInstance("TLS");  // ("TLS", "SunJSSE");
            sslContext.init(null, tm, new java.security.SecureRandom());
            return sslContext.getSocketFactory();
        }
        catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static void setCharSet(String charSet) {
        if (charSet.isEmpty()) {
            throw new IllegalArgumentException("charSet can not be blank.");
        }
        HttpKit.CHARSET = charSet;
    }

    private static HttpURLConnection getHttpConnection(String url, String method, Map<String, String> headers) throws IOException, NoSuchAlgorithmException, NoSuchProviderException, KeyManagementException {
        URL _url = new URL(url);
        HttpURLConnection conn = (HttpURLConnection)_url.openConnection();
        if (conn instanceof HttpsURLConnection) {
            ((HttpsURLConnection)conn).setSSLSocketFactory(sslSocketFactory);
            ((HttpsURLConnection)conn).setHostnameVerifier(trustAnyHostnameVerifier);
        }

        conn.setRequestMethod(method);
        conn.setDoOutput(true);
        conn.setDoInput(true);

        conn.setConnectTimeout(19000);
        conn.setReadTimeout(19000);

        conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
        conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36");

        if (headers != null && !headers.isEmpty())
            for (Entry<String, String> entry : headers.entrySet())
                conn.setRequestProperty(entry.getKey(), entry.getValue());

        return conn;
    }

    /**
     * Send GET request
     */
    public static String get(String url, Map<String, String> queryParas, Map<String, String> headers) {
        HttpURLConnection conn = null;
        try {
            conn = getHttpConnection(buildUrlWithQueryString(url, queryParas), GET, headers);
            conn.connect();
            return readResponseString(conn);
        }
        catch (Exception e) {
            throw new RuntimeException(e);
        }
        finally {
            if (conn != null) {
                conn.disconnect();
            }
        }
    }

    public static String get(String url, Map<String, String> queryParas) {
        return get(url, queryParas, null);
    }

    public static String get(String url) {
        return get(url, null, null);
    }

    /**
     * Send POST request
     */
    public static String post(String url, Map<String, String> queryParas, String data, Map<String, String> headers) {
        HttpURLConnection conn = null;
        try {
            conn = getHttpConnection(buildUrlWithQueryString(url, queryParas), POST, headers);
            conn.connect();

            OutputStream out = conn.getOutputStream();
            out.write(data.getBytes(CHARSET));
            out.flush();
            out.close();

            return readResponseString(conn);
        }
        catch (Exception e) {
            throw new RuntimeException(e);
        }
        finally {
            if (conn != null) {
                conn.disconnect();
            }
        }
    }

    public static String post(String url, Map<String, String> queryParas, String data) {
        return post(url, queryParas, data, null);
    }

    public static String post(String url, String data, Map<String, String> headers) {
        return post(url, null, data, headers);
    }

    public static String post(String url, String data) {
        return post(url, null, data, null);
    }

    private static String readResponseString(HttpURLConnection conn) {
        StringBuilder sb = new StringBuilder();
        InputStream inputStream = null;
        try {
            inputStream = conn.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, CHARSET));
            String line = null;
            while ((line = reader.readLine()) != null){
                sb.append(line).append("\n");
            }
            return sb.toString();
        }
        catch (Exception e) {
            throw new RuntimeException(e);
        }
        finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                }
            }
        }
    }

    /**
     * Build queryString of the url
     */
    private static String buildUrlWithQueryString(String url, Map<String, String> queryParas) {
        if (queryParas == null || queryParas.isEmpty())
            return url;

        StringBuilder sb = new StringBuilder(url);
        boolean isFirst;
        if (url.indexOf("?") == -1) {
            isFirst = true;
            sb.append("?");
        }
        else {
            isFirst = false;
        }

        for (Entry<String, String> entry : queryParas.entrySet()) {
            if (isFirst) isFirst = false;   
            else sb.append("&");

            String key = entry.getKey();
            String value = entry.getValue();
            if (!value.isEmpty())
                try {value = URLEncoder.encode(value, CHARSET);} catch (UnsupportedEncodingException e) {throw new RuntimeException(e);}
            sb.append(key).append("=").append(value);
        }
        return sb.toString();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
public class MD5 {
    public static String MD5sign(String s) {
        char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
        try {
            byte[] btInput = s.getBytes("UTF-8");
            // Getting MessageDigest Objects for MD5 Digest Algorithms
            MessageDigest mdInst = MessageDigest.getInstance("MD5");
            // Update summary with specified bytes
            mdInst.update(btInput);
            // Obtain ciphertext
            byte[] md = mdInst.digest();
            // Converting ciphertext to hexadecimal string form
            int j = md.length;
            char str[] = new char[j * 2];
            int k = 0;
            for (int i = 0; i < j; i++) {
                byte byte0 = md[i];
                str[k++] = hexDigits[byte0 >>> 4 & 0xf];
                str[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(str).toLowerCase();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    public static void main(String[] args) {
        System.out.println(MD5sign("Hello world"));
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

AsyncTask is used to asynchronously obtain the parameters related to the initiation of Wechat Payment. Of course, you can also use other asynchronous network request open source frameworks

public class TestPayPrepay extends AsyncTask<Object, Integer, String> {
    private Context mContext;
    public TestPayPrepay(Context context) {
        this.mContext = context;
    }

    @Override
    protected String doInBackground(Object... params) {
        System.out.println("TestPayPrepay doInBackground");
        return  IPayLogic.getIntance(mContext).testPay();
    }

    @Override
    protected void onPostExecute(String result) {
        try {
            if (result!=null) {
                System.out.println("TestPayPrepay result>"+result);
                JSONObject data = new JSONObject(result);
                if(!data.has("code")){
                    String sign = data.getString("sign");
                    String timestamp = data.getString("timestamp");
                    String noncestr = data.getString("noncestr");
                    String partnerid = data.getString("partnerid");
                    String prepayid = data.getString("prepayid");
                    String appid = data.getString("appid");
                    Toast.makeText(mContext, "Payment is being mobilized", Toast.LENGTH_SHORT).show();

                    Constants.APP_ID = appid;

                    IPayLogic.getIntance(mContext).startWXPay(appid, partnerid, prepayid, noncestr, timestamp, sign);
                }else{
                    String message = data.getString("message");
                    Log.d("PAY_GET", "Return error"+message);
                    Toast.makeText(mContext, "Return error:"+message, Toast.LENGTH_SHORT).show();
                }
            }else {
                System.out.println("get  prepayid exception, is null");
            }
        } catch (Exception e) {
            Log.e("PAY_GET", "Abnormal:"+e.getMessage());
            Toast.makeText(mContext, "Abnormal:"+e.getMessage(), Toast.LENGTH_SHORT).show();
        }
        super.onPostExecute(result);
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48

Payment Result Callback

 <activity
            android:name="[Application package name].wxapi.WXPayEntryActivity"
            android:exported="true"
            android:theme="@android:style/Theme.Translucent"
            android:launchMode="singleTop" >
 </activity>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

The encapsulation is SDK, so a transparent theme is set up here.

public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler{
    private IWXAPI api;
    private IPayListener payListener;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        requestWindowFeature(Window.FEATURE_NO_TITLE);//Hidden title
        LinearLayout ll = new LinearLayout(this);
        setContentView(ll);
        api = WXAPIFactory.createWXAPI(this, Constants.APP_ID);
        api.handleIntent(getIntent(), this);
        finish();
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        setIntent(intent);
        api.handleIntent(intent, this);
    }

    @Override
    public void onReq(BaseReq req) {
    }

    @Override
    public void onResp(BaseResp resp) {
        payListener = Constants.payListener;
        int code = resp.errCode;  
        System.out.println("onResp errCode>"+code);
        if (payListener!=null) {
            payListener.onPay(code);
            System.out.println("payListener callback");
        }else {
            System.out.println("payListener not callback");
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

Note: If the callback code keeps returning - 1
1. Please check if the application package name and the signature of apk are consistent with the one you submitted to the Wechat Open Platform.
2. Please check whether the parameters returning to the call for payment by Wechat are correct.
Most of the reasons are the first one.

Legacy problem: Since WXPayEntry Activity cannot be encapsulated in jar due to the package name of the payment application is not fixed, it is necessary to add. wxapi to the payment application alone and copy WXPayEntry Activity into the package. If there is a good solution, please leave a message.

Wechat Development Series of articles http://www.jianshu.com/p/a172a1b69fdd

Recommended reading
Speedy Development of Wechat Public Number Wechat Payment 
Quick Development of Public Number Payment for Wechat Public Number 
Quick Development of Wikipedia Public Number Sweep Payment 
Quick Development of Wechat Public Card Payment 
Quickly Develop the Cash Red Pack of Wechat Public Number 
Quickly Develop Template Message of Wechat Public Number

If this article is helpful to you, please click like to tell me

Server source address: http://git.oschina.net/javen205/weixin_guide 
Client source address: https://github.com/Javen205/JPay

Posted by goldlikesnow on Sat, 22 Jun 2019 14:14:38 -0700