Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android 集成微信支付和支付寶

Android 集成微信支付和支付寶

編輯:關於Android編程

最近比較閒,公司項目更換後台,於是自己來研究微信支付和支付寶支付,把自己學習的過程寫下來,以備以後查看。

注:要集成微信支付和支付寶功能,必須要有以下幾個配置信息,而這寫信息需要公司去微信支付和支付寶開放平台申請並提供給開發者,當然自己也可以去申請,這裡作者用的是公司提供的,這裡不糾結這些過程。獲得這些信息以後

將配置信息放到一個靜態類中,以共統一使用,但是處於安全考慮,微信與支付寶推薦這些數據放到服務器,這裡作者把他們都放在前端,整個過程都是前端處理,實際開發盡量預處理訂單生成放到後端處理。
public class ParameterConfig {
	
	public static final String  GANHOST = "http://101.226.197.11"; //服務器地址ip(根據自己替換)

	/**
	 * 微信
	 */
   	 //appid
	public static final String WX_APP_ID = "";// 自己填寫自己項目的
	// 商戶號
	public static final String WX_MCH_ID = "";// 自己填寫自己項目的
	// API密鑰,在商戶平台設置
	public static final String WX_API_KEY = "";// 自己填寫自己項目的
	//服務器回調接口
	public static final String WX_notifyUrl = GANHOST+"/service/orderComplete";// 用於微信支付成功的回調(按自己需求填寫)

	
	/**
	 * 支付寶
	 */
	// 商戶PID
	public static final String PARTNER = "";//自己填寫自己項目的
	// 商戶收款賬號
	public static final String SELLER = "";//自己填寫自己項目的
	// 商戶私鑰,pkcs8格式
	public static final String RSA_PRIVATE = "";//自己填寫自己項目的
	
	public static final String aliPay_notifyURL = GANHOST+"/service/alipay/orderComplete";//支付寶支付成功的回調
	
}

1.微信支付的集成前提條件

1.首先需要導入微信jar包,從開放平台可以下載到,加入到libs目錄即可
2.配置manifest

	a.用戶權限
	<uses-permission android:name="android.permission.INTERNET">
  	<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS">
  	<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE">	</uses-permission></uses-permission></uses-permission>

b.activity配置,這裡com.gan.mypay改成自己的包名(如果自己包名與src下的package 名不一樣,這裡要的是在manifest中配置的名稱,同樣需要在src建立以自己包 名為路勁的package,一定確保有這個activity)這個activity是微信支付結果要回調的activty

android:name="com.gan.mypay.wxapi.WXPayEntryActivity"
android:exported="true"
android:launchMode="singleTop"/>

2.支付寶支付的集成前提條件

1.首先需要導入微信jar包,從開放平台可以下載到,加入到libs目錄即可
2.配置manifest

a.用戶權限  
	<uses-permission android:name="android.permission.INTERNET">
  	<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS">
  	<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission></uses-permission></uses-permission>

b.activity配置這裡必須要這麼配置


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

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

3.代碼集成

1.首先要有個商品頁面MainActivity,用來手機收集商品信息,這裡需要後台交互生成訂單,我偷懶就直接在頁面生成了假訂單

商品詳情頁 MainActivity.java(這裡用了xutils的注入)
@ContentView(R.layout.activity_main)
public class MainActivity extends Activity {

	
	private Goods goods;
	private String username;
	private String mobile;
	private String adress;
	private int count;

	@ViewInject(R.id.product_ordsubmit_username)
	private TextView usernameTV;
	
	@ViewInject(R.id.product_ordsubmit_phone)
	private TextView phoneTV;

	@ViewInject(R.id.product_ordsubmit_adress)
	private TextView adressTV;

	@ViewInject(R.id.product_ordsubmit_desc)
	private TextView descTV;
	
	@ViewInject(R.id.product_ordsubmit_price)
	private TextView priceTV;
	
	@ViewInject(R.id.product_ordsubmit_intg)
	private TextView intgTV;
	
	@ViewInject(R.id.product_ordsubmit_count1)
	private TextView countTV1;
	
	@ViewInject(R.id.product_ordsubmit_count)
	private TextView countTV;
	
	@ViewInject(R.id.product_ordsubmit_intgtotal1)
	private TextView intgtotal1TV;
	
	@ViewInject(R.id.product_ordsubmit_intgtotal2)
	private TextView intgtotal2TV;
	
	@ViewInject(R.id.product_ordsubmit_pricetotal1)
	private TextView pricetotal1TV;
	
	@ViewInject(R.id.product_ordsubmit_pricetotal2)
	private TextView pricetotal2TV;
	
	@ViewInject(R.id.product_ordsubmit_counttotal)
	private TextView counttotalTV;
	
	@ViewInject(R.id.product_ordsubmit_ok)
	private Button okBtn;
	
	@ViewInject(R.id.product_ordsubmit_say_et)
	private TextView sayEt;
	
	@ViewInject(R.id.product_ordsubmit_img)
	private ImageView img;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		ViewUtils.inject(this);
		goods = new Goods();
		goods.costprice=100;
		goods.productid=692356222;
		goods.producttypeid=11;
		goods.productname="測試商品";
		goods.discountprice=0.01;
		goods.productdescription="商品描述";
		goods.companydesc="測試商戶簡單描述";
		goods.comanyadress="商戶地址未知";
		goods.companyname="測試商戶";
		goods.score=1;
		goods.status=1;
		goods.stock=300;
		count=1;
		initData();
		initView();
	}

	
	
	private void initData() {
		
			username ="客戶名稱";
			mobile = "13800380038";
			adress="客戶地址";
			
	}



	private void initView() {	
			usernameTV.setText("收貨人:"+username);
			phoneTV.setText(mobile+"");
			adressTV.setText(adress);
			descTV.setText(goods.productdescription);
			priceTV.setText("¥"+goods.discountprice);
			intgTV.setText("積分:"+goods.score);
			countTV1.setText("X"+count);
			countTV.setText(count+"");
			intgtotal1TV.setText("共得到"+count*goods.score+"積分");
			intgtotal2TV.setText("積分:"+count*goods.score);
			counttotalTV.setText("共"+count+"件");
			pricetotal1TV.setText("¥"+Arith.mul(goods.discountprice, count));
			pricetotal2TV.setText("¥"+Arith.mul(goods.discountprice, count));
			//ImageLoader.getInstance().displayImage(goods.pic1, img);
	}

	/**
	 * 增加數量
	 * @param v
	 */
	@OnClick(R.id.product_ordsubmit_count_add)
	public void add(View v) {
		count++;
		countTV1.setText("X"+count);
		countTV.setText(count+"");
		intgtotal1TV.setText("共得到"+count*goods.score+"積分");
		intgtotal2TV.setText("積分:"+count*goods.score);
		counttotalTV.setText("共"+count+"件");
		pricetotal1TV.setText("¥"+Arith.mul(goods.discountprice, count));
		pricetotal2TV.setText("¥"+Arith.mul(goods.discountprice, count));
	}

	/**
	 * 減少數量
	 * @param v
	 */
	@OnClick(R.id.product_ordsubmit_count_sub)
	public void sub(View v) {
		if (count>1) {
			count--;
			countTV1.setText("X"+count);
			countTV.setText(count+"");
			intgtotal1TV.setText("共得到"+count*goods.score+"積分");
			intgtotal2TV.setText("積分:"+count*goods.score);
			counttotalTV.setText("共"+count+"件");
			pricetotal1TV.setText("¥"+Arith.mul(goods.discountprice, count));
			pricetotal2TV.setText("¥"+Arith.mul(goods.discountprice, count));
		}
	}
	
	
	/**
	 * 提交訂單
	 * @param v
	 */
	@OnClick(R.id.product_ordsubmit_ok)
	public void submit(View v) {
		
		final OrderInfo orderInfo=new OrderInfo();
		orderInfo.userid=13752;
		orderInfo.areacode=23;
		orderInfo.buildno="10";
		orderInfo.roomno="1001";
		orderInfo.producttypeid=goods.producttypeid;
		orderInfo.productid=goods.productid;
		orderInfo.amount=goods.discountprice;//單價
		orderInfo.account=count;//數量
		orderInfo.totalamount=Arith.mul(goods.discountprice, count);
		//double offsetamount;//抵扣金額
		orderInfo.score=count*goods.score;
		//int assessitem;//評價項
		//int assesslevel;//評價級別
		//String assesscontent;//評價內容
		//long payid=;//支付編號
		orderInfo.status=2;//支付狀態待付款
		orderInfo.type=11;//日用品
		orderInfo.usermemo =sayEt.getText().toString();//業主備注
		orderInfo.address =adress;
		orderInfo.productname =goods.productname;//
		orderInfo.desccontext =goods.productdescription;//
		orderInfo.outtradeno=System.currentTimeMillis()+""+orderInfo.userid;
		orderInfo.merchantid=goods.companyid;
		submitorder(orderInfo);
	}
	/**
	 * 訂單提交成功,進入付款界面
	 * @param orderInfo 
	 * @return
	 */
	private void submitorder(OrderInfo orderInfo) {
		Intent intent=new Intent(this, SelectPayTypeActivity.class);
		intent.putExtra("data", orderInfo);
		startActivity(intent);
	}
}
	activty_main.xml

                                                   

2.在mainactivty中點擊確認按鈕調用支付方式選擇頁面SelectPayTypeActivity,用來發起支付選擇

vcq9" height="800" src="/uploadfile/Collfiles/20160513/20160513091715387.png" width="480" />
SelectPayTypeActivity.java

@ContentView(R.layout.activity_select_pay_type) public class SelectPayTypeActivity extends Activity { @ViewInject(R.id.paytype_of_weixin_ck) private CheckBox weixinCK; @ViewInject(R.id.paytype_of_zhifubao_ck) private CheckBox zhifubaoCK; @ViewInject(R.id.last_pay_count_tv) private TextView payCountTv; private OrderInfo orderInfo; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ViewUtils.inject(this); initData(); initView(); } private void initView() { payCountTv.setText("¥"+orderInfo.totalamount); } private void initData() { orderInfo=(OrderInfo) getIntent().getSerializableExtra("data"); } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); int code=intent.getIntExtra("result", 1); switch (code) { case 0://表示成功 finish(); break; case -1://表示失敗 finish(); break; case -2:////表示取消 finish(); break; case 1://未知不做處理 break; default: break; } } @OnClick(R.id.paytype_of_weixin) public void wx(View v) { if (zhifubaoCK.isChecked()) { zhifubaoCK.setChecked(false); } if (!weixinCK.isChecked()) { weixinCK.setChecked(true); } } @OnClick(R.id.paytype_of_zhifubao) public void zfb(View v) { if (weixinCK.isChecked()) { weixinCK.setChecked(false); } if (!zhifubaoCK.isChecked()) { zhifubaoCK.setChecked(true); } } @OnClick(R.id.paytype_of_weixin_ck) public void wxck(View v) { if (zhifubaoCK.isChecked()) { zhifubaoCK.setChecked(false); } if (!weixinCK.isChecked()) { weixinCK.setChecked(true); } } @OnClick(R.id.paytype_of_zhifubao_ck) public void zfbck(View v) { if (weixinCK.isChecked()) { weixinCK.setChecked(false); } if (!zhifubaoCK.isChecked()) { zhifubaoCK.setChecked(true); } } @OnClick(R.id.btn_pay_submit) public void paysubmit(View v) { if (weixinCK.isChecked()) { if (!isWeixinAvilible(this)) { Toast.makeText(this, "請先安裝微信或者選擇其他支付方式",0).show(); return; } //微信支付 payByWX(handler,orderInfo); }else{ if (!isZfbAvilible(this)) { Toast.makeText(this, "請先安支付寶或者選擇其他支付方式",0).show(); return; } //支付寶支付 payByzfb(handler,orderInfo); } } Handler handler=new Handler(){ @Override public void handleMessage(Message msg) { switch (msg.what) { case 9000://支付寶支付成功 Intent it; finish(); break; case 8000://支付寶支付失敗 finish(); break; default: break; } } }; /** * 調用支付寶支付 * @param handler * @param order */ private void payByzfb(Handler handler, OrderInfo order) { AlipayUtil alipay=new AlipayUtil(this,order,handler); } /** * 調用微信支付 * @param handler * @param orderInfo2 */ private void payByWX(Handler handler, OrderInfo order) { WXpayUtil wxpay=new WXpayUtil(this,order); } /** * 檢查微信是否存在 * @param context * @return */ public boolean isWeixinAvilible(Context context) { PackageManager packageManager = context.getPackageManager();// 獲取packagemanager List pinfo = packageManager.getInstalledPackages(0);// 獲取所有已安裝程序的包信息 if (pinfo != null) { for (int i = 0; i < pinfo.size(); i++) { String pn = pinfo.get(i).packageName; System.out.println(pinfo.get(i).packageName); if (pn.equals("com.tencent.mm")) { return true; } } } return false; } /** * 檢查支付包是否存在 * @param context * @return */ private boolean isZfbAvilible(Context context) { PackageManager packageManager = context.getPackageManager();// 獲取packagemanager List pinfo = packageManager.getInstalledPackages(0);// 獲取所有已安裝程序的包信息 if (pinfo != null) { for (int i = 0; i < pinfo.size(); i++) { String pn = pinfo.get(i).packageName; System.out.println(pinfo.get(i).packageName); if (pn.equals("com.alipay.android.app")) { return true; } } } return false; } }
activty_selecte_pay_type.xml


                     

3.根據支付方式調用對應工具類微信(WXpayUtil),支付寶(AlipayUtil)

 


WXpayUtil.java

public class WXpayUtil {
	private IWXAPI api;
	private OrderInfo order;
	private Context context;
	private PayReq req;
	private Map resultunifiedorder;
	private static final String TAG = "ewuye.online.SelectPayTypeActivity";

	public WXpayUtil(Context mcontext,OrderInfo order){
		//初始化微信支付
		this.order=order;
		this.context=mcontext;
		if (TextUtils.isEmpty(ParameterConfig.WX_APP_ID) || TextUtils.isEmpty(ParameterConfig.WX_MCH_ID) || TextUtils.isEmpty(ParameterConfig.WX_API_KEY)) {
			new AlertDialog.Builder(context).setTitle("警告").setMessage("需要配置WX_APP_ID | WX_MCH_ID| WX_API_KEY\n請到ParameterConfig.java裡配置")
					.setPositiveButton("確定", new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialoginterface, int i) {
							//
							((Activity)context).finish();
						}
					}).show();
			return;
		}
		
		api = WXAPIFactory.createWXAPI(context, null);
		req = new PayReq();
		//生成prepay_id
		GetPrepayIdTask getPrepayId = new GetPrepayIdTask();
		getPrepayId.execute();
	}
	
	/**
	 * 用於獲取
	 * @author 95
	 *
	 */
	private class GetPrepayIdTask extends AsyncTask> {

		private ProgressDialog dialog;


		@Override
		protected void onPreExecute() {
			dialog = ProgressDialog.show(context, "提示", "正在獲取預支付訂單...");
		}

		@Override
		protected void onPostExecute(Map result) {
			if (dialog != null) {
				dialog.dismiss();
			}
			resultunifiedorder=result;
			genPayReq();
			
		}

		@Override
		protected void onCancelled() {
			super.onCancelled();
		}

		@Override
		protected Map  doInBackground(Void... params) {

			String url = String.format("https://api.mch.weixin.qq.com/pay/unifiedorder");
			String entity = genProductArgs();

			Log.e("orion",entity);

			byte[] buf = httpPost(url, entity);

			String content = new String(buf);
			Log.e("orion", content);
			Map xml=decodeXml(content);

			return xml;
		}
	}
	
	
	private void genPayReq() {

		req.appId = ParameterConfig.WX_APP_ID;
		req.partnerId = ParameterConfig.WX_MCH_ID;
		req.prepayId = resultunifiedorder.get("prepay_id");
		req.packageValue = "prepay_id="+resultunifiedorder.get("prepay_id");
		req.nonceStr = genNonceStr();
		req.timeStamp = String.valueOf(genTimeStamp());


		List signParams = new LinkedList();
		signParams.add(new BasicNameValuePair("appid", req.appId));
		signParams.add(new BasicNameValuePair("noncestr", req.nonceStr));
		signParams.add(new BasicNameValuePair("package", req.packageValue));
		signParams.add(new BasicNameValuePair("partnerid", req.partnerId));
		signParams.add(new BasicNameValuePair("prepayid", req.prepayId));
		signParams.add(new BasicNameValuePair("timestamp", req.timeStamp));
		
		req.sign = genAppSign(signParams);
		Log.e("orion", signParams.toString());
		sendPayReq();
	}
	private void sendPayReq() {
		api.registerApp(ParameterConfig.WX_APP_ID);
		api.sendReq(req);
		
	}
	
	private String genProductArgs() {
		StringBuffer xml = new StringBuffer();

		try {
			String	nonceStr = genNonceStr();
			xml.append("");
           List packageParams = new LinkedList();
			packageParams.add(new BasicNameValuePair("appid", ParameterConfig.WX_APP_ID));
			packageParams.add(new BasicNameValuePair("body", order.productname));
			packageParams.add(new BasicNameValuePair("mch_id", ParameterConfig.WX_MCH_ID));
			packageParams.add(new BasicNameValuePair("nonce_str", nonceStr));
			packageParams.add(new BasicNameValuePair("notify_url", ParameterConfig.WX_notifyUrl));
			packageParams.add(new BasicNameValuePair("out_trade_no",genOutTradNo()));
			packageParams.add(new BasicNameValuePair("spbill_create_ip","127.0.0.1"));
			packageParams.add(new BasicNameValuePair("total_fee", (int)(order.totalamount*100)+""));
			packageParams.add(new BasicNameValuePair("trade_type", "APP"));


			String sign = genPackageSign(packageParams);
			packageParams.add(new BasicNameValuePair("sign", sign));
			
			

		   String xmlstring =toXml(packageParams);
		   return new String(xmlstring.toString().getBytes(), "ISO8859-1");
			//return xmlstring;

		} catch (Exception e) {
			Log.e(TAG, "genProductArgs fail, ex = " + e.getMessage());
			return null;
		}
		

	}
	
	private String genAppSign(List params) {
		StringBuilder sb = new StringBuilder();

		for (int i = 0; i < params.size(); i++) {
			sb.append(params.get(i).getName());
			sb.append('=');
			sb.append(params.get(i).getValue());
			sb.append('&');
		}
		sb.append("key=");
		sb.append(ParameterConfig.WX_API_KEY);

        
		String appSign = getMessageDigest(sb.toString().getBytes());
		Log.e("orion",appSign);
		return appSign;
	}
	
	
	private  HttpClient getNewHttpClient() { 
		   try { 
		       KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); 
		       trustStore.load(null, null); 

		       SSLSocketFactory sf = new SSLSocketFactoryEx(trustStore); 
		       sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); 

		       HttpParams params = new BasicHttpParams(); 
		       HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); 
		       HttpProtocolParams.setContentCharset(params, HTTP.UTF_8); 

		       SchemeRegistry registry = new SchemeRegistry(); 
		       registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); 
		       registry.register(new Scheme("https", sf, 443)); 

		       ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry); 

		       return new DefaultHttpClient(ccm, params); 
		   } catch (Exception e) { 
		       return new DefaultHttpClient(); 
		   } 
		}
	private class SSLSocketFactoryEx extends SSLSocketFactory {      
	      
	    SSLContext sslContext = SSLContext.getInstance("TLS");      
	      
	    public SSLSocketFactoryEx(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {      
	        super(truststore);      
	      
	        TrustManager tm = new X509TrustManager() {      
	      
	            public X509Certificate[] getAcceptedIssuers() {      
	                return null;      
	            }      
	      
				@Override
				public void checkClientTrusted(X509Certificate[] chain, String authType) throws java.security.cert.CertificateException {
				}

				@Override
				public void checkServerTrusted(X509Certificate[] chain,	String authType) throws java.security.cert.CertificateException {
				}  
	        };      
	      
	        sslContext.init(null, new TrustManager[] { tm }, null);      
	    }      
	      
		@Override
		public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
			return sslContext.getSocketFactory().createSocket(socket, host,	port, autoClose);
		}

		@Override
		public Socket createSocket() throws IOException {
			return sslContext.getSocketFactory().createSocket();
		} 
	}  
	public  byte[] httpPost(String url, String entity) {
		if (url == null || url.length() == 0) {
			Log.e(TAG, "httpPost, url is null");
			return null;
		}
		
		HttpClient httpClient = getNewHttpClient();
		HttpPost httpPost = new HttpPost(url);
		
		try {
			httpPost.setEntity(new StringEntity(entity));
			httpPost.setHeader("Accept", "application/json");
			httpPost.setHeader("Content-type", "application/json");
			
			HttpResponse resp = httpClient.execute(httpPost);
			if (resp.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
				Log.e(TAG, "httpGet fail, status code = " + resp.getStatusLine().getStatusCode());
				return null;
			}

			return EntityUtils.toByteArray(resp.getEntity());
		} catch (Exception e) {
			Log.e(TAG, "httpPost exception, e = " + e.getMessage());
			e.printStackTrace();
			return null;
		}
	}
	
	private String genOutTradNo() {
		Random random = new Random();
		return getMessageDigest(String.valueOf(random.nextInt(10000)).getBytes());
	}
	
	public Map decodeXml(String content) {

		try {
			Map xml = new HashMap();
			XmlPullParser parser = Xml.newPullParser();
			parser.setInput(new StringReader(content));
			int event = parser.getEventType();
			while (event != XmlPullParser.END_DOCUMENT) {

				String nodeName=parser.getName();
				switch (event) {
					case XmlPullParser.START_DOCUMENT:

						break;
					case XmlPullParser.START_TAG:

						if("xml".equals(nodeName)==false){
							//實例化student對象
							xml.put(nodeName,parser.nextText());
						}
						break;
					case XmlPullParser.END_TAG:
						break;
				}
				event = parser.next();
			}

			return xml;
		} catch (Exception e) {
			Log.e("orion",e.toString());
		}
		return null;

	}

	private String genNonceStr() {
		Random random = new Random();
		return getMessageDigest(String.valueOf(random.nextInt(10000)).getBytes());
	}
	
	private long genTimeStamp() {
		return System.currentTimeMillis() / 1000;
	}
	
	public  String getMessageDigest(byte[] buffer) {
		char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
		try {
			MessageDigest mdTemp = MessageDigest.getInstance("MD5");
			mdTemp.update(buffer);
			byte[] md = mdTemp.digest();
			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);
		} catch (Exception e) {
			return null;
		}
	}
	
	/**
	 生成簽名
	 */

	private String genPackageSign(List params) {
		StringBuilder sb = new StringBuilder();
		
		for (int i = 0; i < params.size(); i++) {
			sb.append(params.get(i).getName());
			sb.append('=');
			sb.append(params.get(i).getValue());
			sb.append('&');
		}
		sb.append("key=");
		sb.append(ParameterConfig.WX_API_KEY);
		

		String packageSign = getMessageDigest(sb.toString().getBytes()).toUpperCase();
		Log.e("orion",packageSign);
		return packageSign;
	}
	
	private String toXml(List params) {
		StringBuilder sb = new StringBuilder();
		sb.append("");
		for (int i = 0; i < params.size(); i++) {
			sb.append("<"+params.get(i).getName()+">");


			sb.append(params.get(i).getValue());
			sb.append("");
		}
		sb.append("");

		Log.e("orion",sb.toString());
		return sb.toString();
	}
}
AlipayUtil.java
public class AlipayUtil {

	private Activity context;
	private OrderInfo order;
	private Handler mhandler;
	private static final int SDK_PAY_FLAG = 1;
	
	
	
	public AlipayUtil(Activity context, OrderInfo order,Handler mhandler) {
		this.context=context;
		this.order=order;
		this.mhandler=mhandler;
		pay();
	}
	
	
	private void pay() {
		//判斷是否注冊商戶到支付寶
		if (TextUtils.isEmpty(ParameterConfig.PARTNER) || TextUtils.isEmpty(ParameterConfig.RSA_PRIVATE) || TextUtils.isEmpty(ParameterConfig.SELLER)) {
			new AlertDialog.Builder(context).setTitle("警告").setMessage("需要配置PARTNER | RSA_PRIVATE| SELLER\n請到ParameterConfig.java裡配置")
					.setPositiveButton("確定", new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialoginterface, int i) {
							//
							((Activity)context).finish();
						}
					}).show();
			return;
		}
		
		String orderInfo = getOrderInfo(order);
		
		/**
		 * 特別注意,這裡的簽名邏輯需要放在服務端,切勿將私鑰洩露在代碼中!
		 */
		String sign = sign(orderInfo);
		try {
			/**
			 * 僅需對sign 做URL編碼
			 */
			sign = URLEncoder.encode(sign, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		
		/**
		 * 完整的符合支付寶參數規范的訂單信息
		 */
		final String payInfo = orderInfo + "&sign=\"" + sign + "\"&" + getSignType();

		Runnable payRunnable = new Runnable() {

			@Override
			public void run() {
				// 構造PayTask 對象
				PayTask alipay = new PayTask(context);
				// 調用支付接口,獲取支付結果
				String result = alipay.pay(payInfo, true);
				
				Message msg = new Message();
				msg.what = SDK_PAY_FLAG;
				msg.obj = result;
				mHandler.sendMessage(msg);
			}
		};
		
		// 必須異步調用
		Thread payThread = new Thread(payRunnable);
		payThread.start();
	}
	
	@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);
				/**
				 * 同步返回的結果必須放置到服務端進行驗證(驗證的規則請看https://doc.open.alipay.com/doc2/
				 * detail.htm?spm=0.0.0.0.xdvAU6&treeId=59&articleId=103665&
				 * docType=1) 建議商戶依賴異步通知
				 */
				String resultInfo = payResult.getResult();// 同步返回需要驗證的信息

				String resultStatus = payResult.getResultStatus();
				// 判斷resultStatus 為“9000”則代表支付成功,具體狀態碼代表含義可參考接口文檔
				if (TextUtils.equals(resultStatus, "9000")) {
					mhandler.sendEmptyMessage(9000);
					//Toast.makeText(context, "支付成功", Toast.LENGTH_SHORT).show();
				} else {
					// 判斷resultStatus 為非"9000"則代表可能支付失敗
					// "8000"代表支付結果因為支付渠道原因或者系統原因還在等待支付結果確認,最終交易是否成功以服務端異步通知為准(小概率狀態)
					if (TextUtils.equals(resultStatus, "8000")) {
						Toast.makeText(context, "支付結果確認中", Toast.LENGTH_SHORT).show();

					} else {
						// 其他值就可以判斷為支付失敗,包括用戶主動取消支付,或者系統返回的錯誤
						Toast.makeText(context, "支付寶支付失敗", Toast.LENGTH_SHORT).show();

					}
					mhandler.sendEmptyMessage(8000);
				}
				break;
			}
			default:
				break;
			}
		};
	};
	/**
	 * create the order info. 創建訂單信息
	 * 
	 */
	private String getOrderInfo(OrderInfo order) {

		// 簽約合作者身份ID
		String orderInfo = "partner=" + "\"" + ParameterConfig.PARTNER + "\"";

		// 簽約賣家支付寶賬號
		orderInfo += "&seller_id=" + "\"" +ParameterConfig.SELLER + "\"";

		// 商戶網站唯一訂單號
		orderInfo += "&out_trade_no=" + "\"" + order.outtradeno + "\"";

		// 商品名稱
		orderInfo += "&subject=" + "\"" + order.productname + "\"";

		// 商品詳情
		orderInfo += "&body=" + "\"" + order.desccontext + "\"";

		// 商品金額
		orderInfo += "&total_fee=" + "\"" +  order.totalamount + "\"";

		// 服務器異步通知頁面路徑
		orderInfo += "¬ify_url=" + "\"" + ParameterConfig.aliPay_notifyURL + "\"";

		// 服務接口名稱, 固定值
		orderInfo += "&service=\"mobile.securitypay.pay\"";

		// 支付類型, 固定值
		orderInfo += "&payment_type=\"1\"";

		// 參數編碼, 固定值
		orderInfo += "&_input_charset=\"utf-8\"";

		// 設置未付款交易的超時時間
		// 默認30分鐘,一旦超時,該筆交易就會自動被關閉。
		// 取值范圍:1m~15d。
		// m-分鐘,h-小時,d-天,1c-當天(無論交易何時創建,都在0點關閉)。
		// 該參數數值不接受小數點,如1.5h,可轉換為90m。
		orderInfo += "&it_b_pay=\"30m\"";

		// extern_token為經過快登授權獲取到的alipay_open_id,帶上此參數用戶將使用授權的賬戶進行支付
		// orderInfo += "&extern_token=" + "\"" + extern_token + "\"";

		// 支付寶處理完請求後,當前頁面跳轉到商戶指定頁面的路徑,可空
		orderInfo += "&return_url=\"m.alipay.com\"";

		// 調用銀行卡支付,需配置此參數,參與簽名, 固定值 (需要簽約《無線銀行卡快捷支付》才能使用)
		// orderInfo += "&paymethod=\"expressGateway\"";

		return orderInfo;
	}

	
	
	/**
	 * sign the order info. 對訂單信息進行簽名
	 * 
	 * @param content
	 *            待簽名訂單信息
	 */
	private String sign(String content) {
		return SignUtils.sign(content, ParameterConfig.RSA_PRIVATE);
	}
	
	/**
	 * get the sign type we use. 獲取簽名方式
	 * 
	 */
	private String getSignType() {
		return "sign_type=\"RSA\"";
	}
}
微信的回調actvity
WXPayEntryActivity.java
package com.gan.mypay.wxapi;
import com.gan.mypay.ParameterConfig;
import com.gan.mypay.R;
import com.gan.mypay.SelectPayTypeActivity;
import com.tencent.mm.sdk.constants.ConstantsAPI;
import com.tencent.mm.sdk.modelbase.BaseReq;
import com.tencent.mm.sdk.modelbase.BaseResp;
import com.tencent.mm.sdk.openapi.IWXAPI;
import com.tencent.mm.sdk.openapi.IWXAPIEventHandler;
import com.tencent.mm.sdk.openapi.WXAPIFactory;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler{
	
	private static final String TAG = "MicroMsg.SDKSample.WXPayEntryActivity";
	
    private IWXAPI api;
   // private TextView reulttv;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.wx_pay_result);
    	api = WXAPIFactory.createWXAPI(this, ParameterConfig.WX_APP_ID);
        api.handleIntent(getIntent(), this);
    }

	@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) {
		Log.d(TAG, "onPayFinish, errCode = " + resp.errCode);
		
		if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) {
			AlertDialog.Builder builder = new AlertDialog.Builder(this);
			builder.setTitle("提示");
			//builder.setMessage(getString(R.string.pay_result_callback_msg, String.valueOf(resp.errCode)));
			builder.show();
			Intent intent;
			int code = resp.errCode;
			switch (code) {
			case 0:
				Toast.makeText(this, "支付成功",0).show();
				intent=new Intent(this,SelectPayTypeActivity.class);
				intent.putExtra("result", 0);
				startActivity(intent);
				finish();
				break;
			case -1:
				Toast.makeText(this, "支付失敗",0).show();
				intent=new Intent(this,SelectPayTypeActivity.class);
				intent.putExtra("result", -1);
				startActivity(intent);
				finish();
				break;
			case -2:
				Toast.makeText(this, "支付取消",0).show();
				intent=new Intent(this,SelectPayTypeActivity.class);
				intent.putExtra("result", -2);
				startActivity(intent);
				finish();
				break;
			default:
				break;
			}
		}
	}
}
 
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved