今天照着教程做了一遍。毕竟不是高级工程师,有些东西只是停留在照葫芦画瓢。通过这一次和前几天的网络编程,知道了大体的流程。
现在会的大概就这两样:
一。能够跟着网上给的API,结合教程,七七八八把代码敲出来(暂时不能仅照着API完全独立把代码敲出来)。
二。同时由于软件环境的不同,报的错千奇百怪,但能有效地解决。
好了,废话不多说了。
1.下载Ping++SDK
网址https://www.pingxx.com/dlsdk。当然要先注册。
Server端选择Java,Client端选择Android
2.Server端
新建Dynamic Web Project(PingXX)
新建servlet。配置如下:
PayServlet.java
package com.example.PayServlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.google.gson.Gson;
import com.pingplusplus.Pingpp;
import com.pingplusplus.exception.PingppException;
import com.pingplusplus.model.Charge;
/**
* Servlet implementation class PayServlet
*/
@WebServlet("/PayServlet")
public class PayServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public PayServlet() {
super();
}
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("application/json;charset=UTF-8");
// apiKey在ping++主页的账户和设置里面有
Pingpp.apiKey = "sk_test_yzvDa99GqTeLanvvbDOy9qrT";
// 获取客户端参数
ServletInputStream in = request.getInputStream();
byte[] bytes = new byte[512];
int len = -1;
StringBuffer sb = new StringBuffer();
while ((len = in.read(bytes)) != -1) {
sb.append(new String(bytes, 0, len));
}
Gson gson = new Gson();
PaymentRequest pay = gson.fromJson(sb.toString(), PaymentRequest.class);
// 获得 charge
Map<String, Object> chargeMap = new HashMap<String, Object>();
// 某些渠道需要添加extra参数,具体参数详见接口文档
chargeMap.put("amount", pay.amount);
chargeMap.put("currency", "cny");
chargeMap.put("subject", "购买一款时髦的手表");// 商品名称
chargeMap.put("body", "瑞士名表");
chargeMap.put("order_no", "1234567890");//每次测试都要修改这里的order_no
chargeMap.put("channel", pay.channel);
chargeMap.put("client_ip", request.getRemoteAddr());
Map<String, String> app = new HashMap<String, String>();
app.put("id", "app_qTenzP0CO4CGirvL");// 应用ID
chargeMap.put("app", app);
try {
// 发起交易请求
Charge charge = Charge.create(chargeMap);
// 向客户端发送消息
PrintWriter pw = response.getWriter();
pw.write(charge.toString());
} catch (PingppException e) {
e.printStackTrace();
}
}
//这个class要放在这个Java文件里,不然会报错classNotDefException。原因不明
//调试了好久
class PaymentRequest {
String channel;// 支付渠道
int amount;// 价钱
public PaymentRequest(String channel, int amount) {
this.channel = channel;
this.amount = amount;
}
}
}
服务器端参考下载下来的pingpp-java-master里面的example。依赖包里面也有(我上传的代码中WEB-INF里面还有index.jsp,是用来测试Server端是否成功用的)
3.Client端
新建Android工程Ping
MainActivity.java
package com.example.ping;
import java.io.IOException;
import android.app.Activity;
import android.app.AlertDialog.Builder;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import com.google.gson.Gson;
import com.pingplusplus.android.PaymentActivity;
import com.squareup.okhttp.MediaType;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.RequestBody;
import com.squareup.okhttp.Response;
public class MainActivity extends Activity implements OnClickListener {
// 银联支付渠道
private static final String CHANNEL_UPACP = "upacp";
private static final int REQUEST_CODE_PAYMENT = 1;
private Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
button = (Button) findViewById(R.id.pay);
button.setOnClickListener(this);
}
private String URL = "http://10.107.56.64:8080/PingXX/PayServlet";
class PaymentTask extends AsyncTask<PaymentRequest, Void, String> {
@Override
protected void onPreExecute() {
// 按键点击之后的禁用,防止重复点击
button.setOnClickListener(null);
}
@Override
protected String doInBackground(PaymentRequest... params) {
PaymentRequest paymentRequest = params[0];
String data = null;
String json = new Gson().toJson(paymentRequest);
try {
// 向Your Ping++ Server SDK请求数据
// URL服务器地址
data = postJson(URL, json);
} catch (Exception e) {
e.printStackTrace();
}
return data;
}
/**
* 获得服务端的charge,调用ping++ sdk。
*/
@Override
protected void onPostExecute(String data) {
if (null == data) {
showMsg("请求出错", "请检查URL", "URL无法获取charge");
return;
}
Log.d("charge", data);
Intent intent = new Intent(MainActivity.this, PaymentActivity.class);
intent.putExtra(PaymentActivity.EXTRA_CHARGE, data);
startActivityForResult(intent, REQUEST_CODE_PAYMENT);
}
}
private static String postJson(String url, String json) throws IOException {
MediaType type = MediaType.parse("application/json; charset=utf-8");
RequestBody body = RequestBody.create(type, json);
// 封装请求对象
Request request = new Request.Builder().url(url).post(body).build();
OkHttpClient client = new OkHttpClient();
// 执行请求
Response response = client.newCall(request).execute();
// 返回请求结果
return response.body().string();
}
/**
* onActivityResult 获得支付结果,如果支付成功,
* 服务器会收到ping++ 服务器发送的异步通知。 最终支付成功根据异步通知为准
*/
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
button.setOnClickListener(this);
// 支付页面返回处理
if (requestCode == REQUEST_CODE_PAYMENT) {
if (resultCode == Activity.RESULT_OK) {
String result = data.getExtras().getString("pay_result");
/*
* 处理返回值 "success" - payment succeed "fail" - payment failed
* "cancel" - user canceld "invalid" - payment plugin not
* installed
*/
String errorMsg = data.getExtras().getString("error_msg"); // 错误信息
String extraMsg = data.getExtras().getString("extra_msg"); // 错误信息
showMsg(result, errorMsg, extraMsg);
}
}
}
public void showMsg(String title, String msg1, String msg2) {
String str = title;
if (null != msg1 && msg1.length() != 0) {
str += "\n" + msg1;
}
if (null != msg2 && msg2.length() != 0) {
str += "\n" + msg2;
}
Builder builder = new Builder(MainActivity.this);
builder.setMessage(str);
builder.setTitle("提示");
builder.setPositiveButton("OK", null);
builder.create().show();
}
class PaymentRequest {
String channel;// 支付渠道
int amount;// 价钱
public PaymentRequest(String channel, int amount) {
this.channel = channel;
this.amount = amount;
}
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.pay) {
new PaymentTask().execute(new PaymentRequest(CHANNEL_UPACP, 100));
}
}
}
客户端端参考下载下来的pingpp-android-master里面的example。
测试结果
界面
准备进入支付页面
进入支付页面
付款成功: