How to access wechat payment in Android App

Time:2022-5-4
catalogue
  • Wechat payment
    • Payment within app
    • Code scanning payment
      • Unified order API
      • Get code_ URL, and use a third-party QR code generation library such as zxing to generate QR code.
      • Query order API

This article briefly introduces the access to wechat payment in android app, including in app payment and code scanning payment. Share + pay Pofei

Wechat payment

Wechat official access document

Payment within app

Source download

Main process:

1. Wechat payment platform registered account

Note: after successful registration and application, you need to set 32 characters of your API key in API security. MD5 encryption is recommended and needs to be properly saved. Because it cannot be viewed.

2. Generate advance payment order

3. Generate signature parameters

4. Start wechat and complete the payment

Code scanning payment

The code scanning payment uses the wechat unified ordering API, and uses mode 2. Mode 1 always says that the URL parameters are wrong, which is incomprehensible according to the official documents.

Unified order API

Unified order API
Based on the above, modify

private String getProductArgs() {
    // TODO Auto-generated method stub
    StringBuffer xml=new StringBuffer();
    try {
      String nonceStr=getNonceStr();
      currentOrderId = getOutTrade();
      xml.append("<xml>");
      List<NameValuePair> packageParams=new LinkedList<NameValuePair>();
      packageParams.add(new BasicNameValuePair("appid", WXConstants.APP_ID));
      packageParams.add(new BasicNameValuePair("body", "APP pay test"));
      packageParams.add(new BasicNameValuePair("mch_id", WXConstants.MCH_ID));
      packageParams.add(new BasicNameValuePair("nonce_str", nonceStr));
			//Callback URL address. This is the third party
      packageParams.add(new BasicNameValuePair("notify_url", "http://www.weixunyunduan.com/yunduanwx/wxpay/getpackage"));
			//The internal order number of the merchant system requires 32 characters and is unique under the same merchant
      packageParams.add(new BasicNameValuePair("out_trade_no", getNonceStr()));
			//App and web payment are submitted to the client, and native payment fills in the machine IP that calls wechat payment API
      packageParams.add(new BasicNameValuePair("spbill_create_ip", "192.168.0.1"));
      packageParams.add(new BasicNameValuePair("total_fee", "1"));
			//Native payment
      packageParams.add(new BasicNameValuePair("trade_type", "NATIVE"));

      String sign=getPackageSign(packageParams);
      packageParams.add(new BasicNameValuePair("sign", sign));
      String xmlString=toXml(packageParams);

      return xmlString;


    } catch (Exception e) {
      // TODO: handle exception
      return null;
    }
  }
	
	
	 private String getOutTrade(){
    return UUID.randomUUID().toString().replace("-", "");
  }

The return value of native request is as follows:


<xml>
<return_code><![CDATA[SUCCESS]]></return_code>
<return_msg><![CDATA[OK]]></return_msg>
<appid><![CDATA[]]></appid>
<mch_id><![CDATA[]]></mch_id>
<nonce_str><![CDATA[]]></nonce_str>
<sign><![CDATA[]]></sign>
<result_code><![CDATA[SUCCESS]]></result_code>
<prepay_id><![CDATA[]]></prepay_id>
<trade_type><![CDATA[NATIVE]]></trade_type>
<code_url><![CDATA[weixin://wxpay/bizpayurl?pr=]></code_url>
</xml>

Get code_ URL, and use a third-party QR code generation library such as zxing to generate QR code.

ZXingUtils

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.PointF;
import android.view.Gravity;
import android.view.View.MeasureSpec;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.TextView;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;

import java.util.Hashtable;

/** 
*
*  	 Tool for generating barcode and QR code
*/
public class ZXingUtils {
	/**
	 *The address or string to be converted when generating QR code can be Chinese
	 * 
	 * @param url
	 * @param width
	 * @param height
	 * @return
	 */
	public static Bitmap createQRImage(String url, final int width, final int height) {
		try {
			//Determine the legitimacy of URL
			if (url == null || "".equals(url) || url.length() < 1) {
				return null;
			}
			Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();
			hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
			//Image data conversion, using matrix conversion
			BitMatrix bitMatrix = new QRCodeWriter().encode(url,
					BarcodeFormat.QR_CODE, width, height, hints);
			int[] pixels = new int[width * height];
			//Next, the two-dimensional code images are generated one by one according to the two-dimensional code algorithm,
			//The two for loops are the result of a horizontal scan of the picture
			for (int y = 0; y < height; y++) {
				for (int x = 0; x < width; x++) {
					if (bitMatrix.get(x, y)) {
						pixels[y * width + x] = 0xff000000;
					} else {
						pixels[y * width + x] = 0xffffffff;
					}
				}
			}
			//Generate QR code image format, using ARGB_ eight thousand eight hundred and eighty-eight
			Bitmap bitmap = Bitmap.createBitmap(width, height,
					Bitmap.Config.ARGB_8888);
			bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
			return bitmap;
		} catch (WriterException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 *Generate barcode
	 *
	 * @param context
	 * @param contents
	 *Content to be generated
	 * @param desiredWidth
	 *Broadband for barcode generation
	 * @param desiredHeight
	 *Height of generated barcode
	 * @param displayCode
	 *Whether to display content under barcode
	 * @return
	 */
	public static Bitmap creatBarcode(Context context, String contents,
									 int desiredWidth, int desiredHeight, boolean displayCode) {
		Bitmap ruseltBitmap = null;
		/**
		 *The width of the space left at both ends of the picture
		 */
		int marginW = 20;
		/**
		 *Code type of barcode
		 */
		BarcodeFormat barcodeFormat = BarcodeFormat.CODE_128;

		if (displayCode) {
			Bitmap barcodeBitmap = encodeAsBitmap(contents, barcodeFormat,
					desiredWidth, desiredHeight);
			Bitmap codeBitmap = creatCodeBitmap(contents, desiredWidth + 2
					* marginW, desiredHeight, context);
			ruseltBitmap = mixtureBitmap(barcodeBitmap, codeBitmap, new PointF(
					0, desiredHeight));
		} else {
			ruseltBitmap = encodeAsBitmap(contents, barcodeFormat,
					desiredWidth, desiredHeight);
		}

		return ruseltBitmap;
	}

	/**
	 *Generate barcode的Bitmap
	 *
	 * @param contents
	 *Content to be generated
	 * @param format
	 *Coding format
	 * @param desiredWidth
	 * @param desiredHeight
	 * @return
	 * @throws WriterException
	 */
	protected static Bitmap encodeAsBitmap(String contents,
										  BarcodeFormat format, int desiredWidth, int desiredHeight) {
		final int WHITE = 0xFFFFFFFF;
		final int BLACK = 0xFF000000;

		MultiFormatWriter writer = new MultiFormatWriter();
		BitMatrix result = null;
		try {
			result = writer.encode(contents, format, desiredWidth,
					desiredHeight, null);
		} catch (WriterException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		int width = result.getWidth();
		int height = result.getHeight();
		int[] pixels = new int[width * height];
		// All are 0, or black, by default
		for (int y = 0; y < height; y++) {
			int offset = y * width;
			for (int x = 0; x < width; x++) {
				pixels[offset + x] = result.get(x, y) ? BLACK : WHITE;
			}
		}

		Bitmap bitmap = Bitmap.createBitmap(width, height,
				Bitmap.Config.ARGB_8888);
		bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
		return bitmap;
	}

	/**
	 *Generate bitmap with display code
	 *
	 * @param contents
	 * @param width
	 * @param height
	 * @param context
	 * @return
	 */
	protected static Bitmap creatCodeBitmap(String contents, int width,
											int height, Context context) {
		TextView tv = new TextView(context);
		LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
				LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
		tv.setLayoutParams(layoutParams);
		tv.setText(contents);
		tv.setHeight(height);
		tv.setGravity(Gravity.CENTER_HORIZONTAL);
		tv.setWidth(width);
		tv.setDrawingCacheEnabled(true);
		tv.setTextColor(Color.BLACK);
		tv.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
				MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
		tv.layout(0, 0, tv.getMeasuredWidth(), tv.getMeasuredHeight());

		tv.buildDrawingCache();
		Bitmap bitmapCode = tv.getDrawingCache();
		return bitmapCode;
	}

	/**
	 *Merge two bitmaps into one
	 * 
	 * @param first
	 * @param second
	 * @param fromPoint
	 *Starting position of the second bitmap (relative to the first bitmap)
	 * @return
	 */
	protected static Bitmap mixtureBitmap(Bitmap first, Bitmap second,
										 PointF fromPoint) {
		if (first == null || second == null || fromPoint == null) {
			return null;
		}
		int marginW = 20;
		Bitmap newBitmap = Bitmap.createBitmap(
				first.getWidth() + second.getWidth() + marginW,
				first.getHeight() + second.getHeight(), Config.ARGB_4444);
		Canvas cv = new Canvas(newBitmap);
		cv.drawBitmap(first, marginW, 0, null);
		cv.drawBitmap(second, fromPoint.x, fromPoint.y, null);
		cv.save(Canvas.ALL_SAVE_FLAG);
		cv.restore();

		return newBitmap;
	}

}

Bitmap bitmap = ZXingUtils.createQRImage(wxUrl,200,200);

code_ URL is a short chain that wechat can recognize.

Users can scan and pay on their mobile phones.

Query order API

Get the payment callback and use the query order API

Query order API

String urlString="https://api.mch.weixin.qq.com/pay/orderquery";
        CheckAsyncTask checkAsyncTask = new CheckAsyncTask();
        checkAsyncTask.execute(urlString);

private class CheckAsyncTask extends AsyncTask<String,Void, Map<String, String>>
  {
    private ProgressDialog dialog;
    @Override
    protected void onPreExecute() {
      // TODO Auto-generated method stub
      super.onPreExecute();
      dialog = ProgressDialog. Show (payactivity. This, "prompt", "viewing order status!");

    }
    @Override
    protected Map<String, String> doInBackground(String... params) {
      // TODO Auto-generated method stub
      String url=String.format(params[0]);
      String entity=getProductCheckArgs();
      byte[] buf= wxUtils.httpPost(url, entity);
      String content = new String(buf);
      Map<String,String> xml=decodeXml(content);
      //You can use XML get("trade_state");  Get the status of the order
      return xml;
    }

    @Override
    protected void onPostExecute(Map<String, String> result) {
      // TODO Auto-generated method stub
      super.onPostExecute(result);
      if (dialog != null) {
        dialog.dismiss();
      }
    }
  }

The above is the details of how to access wechat payment in android app. For more information about accessing wechat payment in android app, please pay attention to other relevant articles of developeppaer!

Recommended Today

JS ES6 asynchronous solution

catalogue The callback function is initially used ES6 asynchronous processing model API tailored for this asynchronous model: promise The callback function is initially used Because there was no clear specification in the original j s official, the parameters in the callback function transmitted from the asynchronous function encapsulated in various third-party libraries were not clearly […]