Android 프로 그래 밍 이 실 현 된 위 챗 결제 기능 상세 설명[데모 소스 코드 다운로드 첨부]

이 사례 는 안 드 로 이 드 프로 그래 밍 이 실현 하 는 위 챗 결제 기능 을 다 루 고 있다.여러분 께 참고 하도록 공유 하 겠 습 니 다.구체 적 으로 는 다음 과 같 습 니 다.
최근 에 회사 에서 Ionic 프레임 워 크 를 만 들 었 습 니 다.프로젝트 에 위 챗 결제 가 필요 합 니 다.어 쩔 수 없 이 저 를 옮 겼 습 니 다.그 동안 도 거의 무 너 졌 습 니 다.다행히 황천 에서 마음 이 있 는 사람 을 저 버 리 지 않 고 다른 사람의 문 서 를 보 았 습 니 다.드디어 프로젝트 에 위 챗 결 제 를 집성 했 습 니 다.다음은 작은 저 로 서 제 경험 을 여러분 께 공유 하고 싶 습 니 다.여러분 께 도움 이 되 기 를 바 랍 니 다.
사용 가능 한 데모 부터 주세요.
demo 코드 는 여 기 를 클릭 하 십시오본 사이트 다운로드
이 demo 는 eclipse 를 바탕 으로 개 발 된 것 으로 블 로 거들 도 Android Studio 에서 위 챗 결 제 를 개발 한 적 이 있 습 니 다.원 리 는 모두 똑 같 습 니 다.여러분 은 이 demo 를 알 게 되 었 습 니 다.AS 에서 도 마찬가지 입 니 다.
(따뜻 한 힌트:여러분 이 다운로드 하면 오류 가 발생 할 수도 있 고 그렇지 않 을 수도 있 습 니 다.다음 오류 해결 방법 을 알려 드 리 겠 습 니 다.1.프로젝트 에 들 어간 WeIXinPay->Build Path->configure build path,잘못된 jar 패 키 지 를 제거 합 니 다.2.자원 을 찾 을 수 없 는 상황 이 발생 할 수 있 습 니 다.이것 은 v7 가방 이 없 거나 v7 가방 을 다운로드 하거나 잘못된 부분 을 모두 삭제 하기 때 문 입 니 다.하나의 주제 일 뿐 보기 싫 은 것 을 삭 제 했 을 뿐 입 니 다.물론 있 는 주제 로 도 사용 할 수 있 습 니 다.또 하나의 문 제 를 제기 해 야 합 니 다.바로 당신 이 안에 있 는 text 에 따라 작 동 하 는 것 이 클 라 이언 트 를 조정 하지 못 할 수도 있 습 니 다.아마도 당신 이 위 챗 클 라 이언 트 를 설치 하지 않 았 을 수도 있 습 니 다.왜냐하면 제 가 판단 을 하지 않 았 기 때 문 입 니 다.이 demo 는 한 번 만 성공 적 으로 지불 할 수 있 는 상황 이 발생 하지 않 을 것 이 며,블 로 거들 은 직접 측정 하여 유효 하 다.나타 나 면 한 번 만 지불 할 수 있 고 당신 의 서명 이 대응 하지 않 았 다 는 것 만 설명 할 수 있 습 니 다)
1.위 챗 오픈 플랫폼 에 가서 위 챗 결제 서 비 스 를 신청 하고 자신의 앱 을 연결 하 는 것 은 구체 적 으로 말 하지 않 지만 반드시 신청 을 완성 하면 세 가지 인 자 를 얻 을 수 있 습 니 다.

//appid          ID
public static final String APP_ID = "";
//             ID
public static final String MCH_ID = "";
// API  ,       
public static final String API_KEY= "";

**갱 점 알림:위 챗 개발 플랫폼 에 패키지 이름과 서명 을 설정 합 니 다.이 가방 의 이름 은 반드시 당신 의 가방 이름과 같 아야 합 니 다.바로 manifest 의 package 입 니 다.서명 은 반드시 당신 이 공식 app 으로 생 성 한 것 과 같 아야 합 니 다(https://open.weixin.qq.com/zh_CN/htmledition/res/dev/download/sdk/Gen_Signature_Android.apk)。
위 챗 은 당신 이 작성 한 가방 이름 에 따라 키 스토어 에 알고리즘 을 만들어 서명 을 생 성 합 니 다.가방 이름과 서명 은 반드시 위 챗 오픈 플랫폼 과 같 아야 합 니 다.그러나 여기 서 주의해 야 할 것 은 정식 버 전 을 발표 하면 공식 app 으로 서명 을 다시 만 든 다음 에 오픈 플랫폼 에서 sign 을 다시 설정 해 야 합 니 다.테스트 버 전의 keystore 는 정식 버 전의 keystore 와 다 르 기 때 문 입 니 다.한 마디 로,당신 이 사용 하 는 키스 토어 에서 생 성 된 sign 은 위 챗 이 플랫폼 을 열 때 와 일치 해 야 합 니 다.**
2.준비 작업 이 완료 되 었 습 니 다.다음은 개발 입 니 다.먼저 위 챗 의 jar 가방 을 다운로드 하여 가 져 옵 니 다.
위 챗 결 제 는 세 단계 로 나 뉜 다.
①.prepayId 생 성

@Override
protected Map<String, String> doInBackground(String... params) {
      // TODO Auto-generated method stub
      String url=String.format(params[0]);
      String entity=getProductArgs();
      Log.e("Simon",">>>>"+entity);
      byte[] buf=Util.httpPost(url, entity);
      String content = new String(buf);
      Log.e("orion", "----"+content);
      Map<String,String> xml=decodeXml(content);
      return xml;
}

②.서명 인자 생 성

private void genPayReq() {
    req.appId = Constants.APP_ID;
    req.partnerId = Constants.MCH_ID;
    if (resultunifiedorder!=null) {
      req.prepayId = resultunifiedorder.get("prepay_id");
      req.packageValue = "prepay_id="+resultunifiedorder.get("prepay_id");
    }
    else {
      Toast.makeText(MainActivity.this, "prepayid  ", Toast.LENGTH_SHORT).show();
    }
    req.nonceStr = getNonceStr();
    req.timeStamp = String.valueOf(genTimeStamp());
    List<NameValuePair> signParams = new LinkedList<NameValuePair>();
    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);
    sb.append("sign
"+req.sign+"

"); textView.setText(sb.toString()); Log.e("Simon", "----"+signParams.toString()); }
③ 전근 지불

/*
*       
*/
private void sendPayReq() {
    msgApi.registerApp(Constants.APP_ID);
    msgApi.sendReq(req);
    Log.i(">>>>>", req.partnerId);
}

다음은 전체 코드 를 드 리 겠 습 니 다. 

package com.alpha.live;
import java.io.StringReader;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.xmlpull.v1.XmlPullParser;
import com.tencent.mm.sdk.modelpay.PayReq;
import com.tencent.mm.sdk.openapi.IWXAPI;
import com.tencent.mm.sdk.openapi.WXAPIFactory;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.util.Xml;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
/**
 * Created by Simon on 2016/12/2.
 */
public class MainActivity extends Activity implements OnClickListener {
  private Button submitButton;
  private Button confirmButton;
  private TextView textView;
  private StringBuffer sb;
  private Map<String,String> resultunifiedorder;
  private PayReq req;
  private final IWXAPI msgApi = WXAPIFactory.createWXAPI(this, null);
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    submitButton=(Button) findViewById(R.id.bt_submit_order);
    confirmButton=(Button) findViewById(R.id.bt_corfirm);
    textView=(TextView) findViewById(R.id.tv_prepay_id);
    submitButton.setOnClickListener(this);
    confirmButton.setOnClickListener(this);
    sb=new StringBuffer();
    req=new PayReq();
  }
  @Override
  public void onClick(View v) {
    // TODO Auto-generated method stub
    switch (v.getId()) {
    case R.id.bt_submit_order:
      String urlString="https://api.mch.weixin.qq.com/pay/unifiedorder";
       PrePayIdAsyncTask prePayIdAsyncTask=new PrePayIdAsyncTask();
       prePayIdAsyncTask.execute(urlString);   //  prepayId
    break;
    case R.id.bt_corfirm:
      genPayReq();//      
      sendPayReq();//    
    break;
    default:
      break;
    }
  }
  /*
   *       
   */
  private void sendPayReq() {
    msgApi.registerApp(Constants.APP_ID);
    msgApi.sendReq(req);
    Log.i(">>>>>", req.partnerId);
  }
  private long genTimeStamp() {
    return System.currentTimeMillis() / 1000;
  }
  private void genPayReq() {
    req.appId = Constants.APP_ID;
    req.partnerId = Constants.MCH_ID;
    if (resultunifiedorder!=null) {
      req.prepayId = resultunifiedorder.get("prepay_id");
      req.packageValue = "prepay_id="+resultunifiedorder.get("prepay_id");
    }
    else {
      Toast.makeText(MainActivity.this, "prepayid  ", Toast.LENGTH_SHORT).show();
    }
    req.nonceStr = getNonceStr();
    req.timeStamp = String.valueOf(genTimeStamp());
    List<NameValuePair> signParams = new LinkedList<NameValuePair>();
    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);
    sb.append("sign
"+req.sign+"

"); textView.setText(sb.toString()); Log.e("Simon", "----"+signParams.toString()); } private String genAppSign(List<NameValuePair> 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(Constants.API_KEY); this.sb.append("sign str
"+sb.toString()+"

"); String appSign = MD5.getMessageDigest(sb.toString().getBytes()); Log.e("Simon","----"+appSign); return appSign; } private class PrePayIdAsyncTask extends AsyncTask<String,Void, Map<String, String>> { private ProgressDialog dialog; @Override protected void onPreExecute() { // TODO Auto-generated method stub super.onPreExecute(); dialog = ProgressDialog.show(MainActivity.this, " ", " "); } @Override protected Map<String, String> doInBackground(String... params) { // TODO Auto-generated method stub String url=String.format(params[0]); String entity=getProductArgs(); Log.e("Simon",">>>>"+entity); byte[] buf=Util.httpPost(url, entity); String content = new String(buf); Log.e("orion", "----"+content); Map<String,String> xml=decodeXml(content); return xml; } @Override protected void onPostExecute(Map<String, String> result) { // TODO Auto-generated method stub super.onPostExecute(result); if (dialog != null) { dialog.dismiss(); } sb.append("prepay_id
"+result.get("prepay_id")+"

"); textView.setText(sb.toString()); resultunifiedorder=result; } } public Map<String,String> decodeXml(String content) { try { Map<String, String> xml = new HashMap<String, String>(); 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("Simon","----"+e.toString()); } return null; } private String getProductArgs() { // TODO Auto-generated method stub StringBuffer xml=new StringBuffer(); try { String nonceStr=getNonceStr(); xml.append("<xml>"); List<NameValuePair> packageParams=new LinkedList<NameValuePair>(); packageParams.add(new BasicNameValuePair("appid",Constants.APP_ID)); packageParams.add(new BasicNameValuePair("body", "APP pay test")); packageParams.add(new BasicNameValuePair("mch_id", Constants.MCH_ID)); packageParams.add(new BasicNameValuePair("nonce_str", nonceStr)); packageParams.add(new BasicNameValuePair("notify_url", "https://www.baidu.com"));// packageParams.add(new BasicNameValuePair("out_trade_no",genOutTradNo())); packageParams.add(new BasicNameValuePair("total_fee", "1")); packageParams.add(new BasicNameValuePair("trade_type", "APP")); 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 genOutTradNo() { Random random = new Random(); // return "dasgfsdg1234"; // , return MD5.getMessageDigest(String.valueOf(random.nextInt(10000)).getBytes()); } // , private String getNonceStr() { // TODO Auto-generated method stub Random random=new Random(); return MD5.getMessageDigest(String.valueOf(random.nextInt(10000)).getBytes()); } /** */ private String getPackageSign(List<NameValuePair> 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(Constants.API_KEY); String packageSign = MD5.getMessageDigest(sb.toString().getBytes()).toUpperCase(); Log.e("Simon",">>>>"+packageSign); return packageSign; } /* * xml */ private String toXml(List<NameValuePair> params) { StringBuilder sb = new StringBuilder(); sb.append("<xml>"); for (int i = 0; i < params.size(); i++) { sb.append("<"+params.get(i).getName()+">"); sb.append(params.get(i).getValue()); sb.append("</"+params.get(i).getName()+">"); } sb.append("</xml>"); Log.e("Simon",">>>>"+sb.toString()); return sb.toString(); } }
다음은 결제 결과 가 있 는 페이지 코드 입 니 다.위 챗 공식 제공 클래스 입 니 다.너 는 매 니 페스트 에 이 종 류 를 등록 해 야 한다.여기 서 주의해 야 할 것 은 이 종 류 는 반드시 wxapi 가방 아래 에 두 어야 한 다 는 것 입 니 다.당신 이 직접 가방 을 새로 만 들 면 됩 니 다.
여러분 이 이 demo 를 직접 실행 할 수 있 도록 제 위 챗 추가 서명 은 모두 현지에서 실 행 됩 니 다.prepayid 와 추가 서명 을 얻 으 려 면 서버 에서 완성 해 야 합 니 다.그리고 최종 결제 반환 결과 도 서버 에서 기준 으로 합 니 다.
*다음은 실행 결과 도*


여러분 은 demo 를 다운로드 한 후에 인 자 를 바 꾸 고 keystore,가방 이름,서명 을 하 세 요.쓸 수 있 을 거 야.
더 많은 안 드 로 이 드 관련 내용 에 관심 이 있 는 독자 들 은 본 사이트 의 주 제 를 볼 수 있다.
본 고 에서 말 한 것 이 여러분 의 안 드 로 이 드 프로 그래 밍 에 도움 이 되 기 를 바 랍 니 다.

좋은 웹페이지 즐겨찾기