Android 프로 그래 밍 이 실 현 된 위 챗 결제 기능 상세 설명[데모 소스 코드 다운로드 첨부]
15960 단어 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,가방 이름,서명 을 하 세 요.쓸 수 있 을 거 야.
더 많은 안 드 로 이 드 관련 내용 에 관심 이 있 는 독자 들 은 본 사이트 의 주 제 를 볼 수 있다.
본 고 에서 말 한 것 이 여러분 의 안 드 로 이 드 프로 그래 밍 에 도움 이 되 기 를 바 랍 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Bitrise에서 배포 어플리케이션 설정 테스트하기이 글은 Bitrise 광고 달력의 23일째 글입니다. 자체 또는 당사 등에서 Bitrise 구축 서비스를 사용합니다. 그나저나 며칠 전 Bitrise User Group Meetup #3에서 아래 슬라이드를 발표했...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.