mirror of
https://gitee.com/egzosn/pay-java-parent.git
synced 2026-06-01 05:19:47 +08:00
初始版本
This commit is contained in:
@@ -0,0 +1,155 @@
|
||||
|
||||
package in.egan.pay.demo.controller;
|
||||
|
||||
|
||||
import in.egan.pay.common.util.str.StringUtils;
|
||||
import in.egan.pay.demo.entity.ApyAccount;
|
||||
import in.egan.pay.demo.entity.PayType;
|
||||
import in.egan.pay.demo.service.ApyAccountService;
|
||||
import in.egan.pay.demo.service.PayResponse;
|
||||
import in.egan.pay.common.api.PayConfigStorage;
|
||||
import in.egan.pay.common.bean.MethodType;
|
||||
import in.egan.pay.common.bean.PayMessage;
|
||||
import in.egan.pay.common.bean.PayOrder;
|
||||
import in.egan.pay.common.bean.PayOutMessage;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import static in.egan.pay.demo.dao.ApyAccountRepository.apyAccounts;
|
||||
|
||||
/**
|
||||
* 发起支付入口
|
||||
* @author: egan
|
||||
* @email egzosn@gmail.com
|
||||
* @date 2016/11/18 0:25
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping
|
||||
public class PayController{
|
||||
|
||||
@Resource
|
||||
private ApyAccountService service;
|
||||
|
||||
|
||||
/**
|
||||
* 这里模拟账户信息增加
|
||||
* @param account
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping("add")
|
||||
public Map<String, Object> add(ApyAccount account){
|
||||
apyAccounts.put(account.getPayId(), account);
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("code", 0);
|
||||
data.put("account", account);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 跳到支付页面
|
||||
* 针对实时支付,即时付款
|
||||
*
|
||||
* @param payId 账户id
|
||||
* @param transactionType 交易类型, 这个针对于每一个 支付类型的对应的几种交易方式
|
||||
* @param bankType 针对刷卡支付,卡的类型,类型值
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "toPay.html", produces = "text/html;charset=UTF-8")
|
||||
public String toPay( Integer payId, String transactionType, String bankType, @RequestParam(value = "0.01")BigDecimal price) {
|
||||
//获取对应的支付账户操作工具(可根据账户id)
|
||||
PayResponse payResponse = service.getPayResponse(payId);
|
||||
|
||||
PayOrder order = new PayOrder("订单title", "摘要", price, UUID.randomUUID().toString().replace("-", ""), PayType.valueOf(payResponse.getStorage().getPayType()).getTransactionType(transactionType));
|
||||
|
||||
//此处只有刷卡支付(银行卡支付)时需要
|
||||
if (StringUtils.isNotEmpty(bankType)){
|
||||
order.setBankType(bankType);
|
||||
}
|
||||
Map orderInfo = payResponse.getService().orderInfo(order);
|
||||
return payResponse.getService().buildRequest(orderInfo, MethodType.POST);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取二维码图像
|
||||
* 二维码支付
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "toQrPay.jpg", produces = "image/jpeg;charset=UTF-8")
|
||||
public byte[] toWxQrPay(Integer payId, String transactionType, @RequestParam(value = "0.01") BigDecimal price) throws IOException {
|
||||
//获取对应的支付账户操作工具(可根据账户id)
|
||||
PayResponse payResponse = service.getPayResponse(payId);
|
||||
//获取订单信息
|
||||
Map<String, Object> orderInfo = payResponse.getService().orderInfo(new PayOrder("订单title", "摘要", price, UUID.randomUUID().toString().replace("-", ""), PayType.valueOf(payResponse.getStorage().getPayType()).getTransactionType(transactionType)));
|
||||
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ImageIO.write(payResponse.getService().genQrPay(orderInfo), "JPEG", baos);
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* 获取支付预订单信息
|
||||
* @param payId 支付账户id
|
||||
* @param transactionType 交易类型
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping("getOrderInfo")
|
||||
public Map<String, Object> getOrderInfo(Integer payId, String transactionType, @RequestParam(value = "0.01") BigDecimal price){
|
||||
//获取对应的支付账户操作工具(可根据账户id)
|
||||
PayResponse payResponse = service.getPayResponse(payId);
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("code", 0);
|
||||
PayOrder order = new PayOrder("订单title", "摘要", price, UUID.randomUUID().toString().replace("-", ""), PayType.valueOf(payResponse.getStorage().getPayType()).getTransactionType(transactionType));
|
||||
data.put("orderInfo", payResponse.getService().orderInfo(order));
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 微信或者支付宝回调地址
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "payBack{payId}.json")
|
||||
public String payBack(HttpServletRequest request, @PathVariable Integer payId) throws IOException {
|
||||
//根据账户id,获取对应的支付账户操作工具
|
||||
PayResponse payResponse = service.getPayResponse(payId);
|
||||
PayConfigStorage storage = payResponse.getStorage();
|
||||
//获取支付方返回的对应参数
|
||||
Map<String, String> params = payResponse.getService().getParameter2Map(request.getParameterMap(), request.getInputStream());
|
||||
if (null == params){
|
||||
return payResponse.getService().getPayOutMessage("fail","失败").toMessage();
|
||||
}
|
||||
|
||||
//校验
|
||||
if (payResponse.getService().verify(params)){
|
||||
PayMessage message = new PayMessage(params, storage.getPayType(), storage.getMsgType().name());
|
||||
PayOutMessage outMessage = payResponse.getRouter().route(message);
|
||||
return outMessage.toMessage();
|
||||
}
|
||||
|
||||
return payResponse.getService().getPayOutMessage("fail","失败").toMessage();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
|
||||
|
||||
|
||||
package in.egan.pay.demo.dao;
|
||||
|
||||
import in.egan.pay.common.bean.MsgType;
|
||||
import in.egan.pay.demo.entity.ApyAccount;
|
||||
import in.egan.pay.demo.entity.PayType;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 账户
|
||||
* @author: egan
|
||||
* @email egzosn@gmail.com
|
||||
* @date 2016/11/18 1:21
|
||||
*/
|
||||
//@Repository
|
||||
public class ApyAccountRepository {
|
||||
|
||||
// 这里简单模拟,引入orm等框架之后可自行删除
|
||||
public static Map<Integer, ApyAccount > apyAccounts = new HashMap<>();
|
||||
|
||||
/**
|
||||
* 这里简单初始化,引入orm等框架之后可自行删除
|
||||
*/
|
||||
{
|
||||
ApyAccount apyAccount1 = new ApyAccount();
|
||||
apyAccount1.setPayId(1);
|
||||
apyAccount1.setPartner("12******01");
|
||||
apyAccount1.setAppid("wxa**********ba9e9");
|
||||
// TODO 2017/2/9 16:20 author: egan sign_type只有单一key时public_key与private_key相等,比如sign_type=MD5的情况
|
||||
apyAccount1.setPublicKey("48gf0iwuhr***********r9weh9eiut9");
|
||||
apyAccount1.setPrivateKey("48gf0iwuhr***********r9weh9eiut9");
|
||||
apyAccount1.setNotifyUrl("http://pay.egan.in/payBack2.json");
|
||||
// 无需同步回调可不填
|
||||
apyAccount1.setReturnUrl("");
|
||||
apyAccount1.setInputCharset("UTF-8");
|
||||
apyAccount1.setSignType("MD5");
|
||||
apyAccount1.setPayType(PayType.wxPay);
|
||||
apyAccount1.setMsgType(MsgType.xml);
|
||||
apyAccounts.put(1, apyAccount1);
|
||||
|
||||
ApyAccount apyAccount2 = new ApyAccount();
|
||||
apyAccount2.setPayId(2);
|
||||
apyAccount2.setPartner("2088****8307");
|
||||
apyAccount2.setPublicKey("MIGfMA0GCSqGSIb3DQEBAQUAA4*****IZwBC2AQ2UBVOrFXfFl75p6/B5KsiNG9zpgmLCUYuLkxpLQIDAQAB");
|
||||
apyAccount2.setPrivateKey("MIICdwIBADANBgkqhkiG9w0BAQ**********g51Vx8BvyypnIfKgw=");
|
||||
apyAccount2.setNotifyUrl("http://pay.egan.in/payBack3.json");
|
||||
// 无需同步回调可不填 app填这个就可以
|
||||
apyAccount2.setReturnUrl("m.alipay.com");
|
||||
apyAccount2.setSeller("egzosn@gmail.com");
|
||||
apyAccount2.setInputCharset("UTF-8");
|
||||
apyAccount2.setSignType("RSA");
|
||||
apyAccount2.setPayType(PayType.aliPay);
|
||||
apyAccount2.setMsgType(MsgType.text);
|
||||
apyAccounts.put(2, apyAccount2);
|
||||
|
||||
}
|
||||
//_____________________________________________________________
|
||||
|
||||
|
||||
/**
|
||||
* 根据id获取对应的账户信息
|
||||
* @param payId 账户id
|
||||
* @return
|
||||
*/
|
||||
public ApyAccount findByPayId(Integer payId){
|
||||
// TODO 2016/11/18 1:23 author: egan 这里简单模拟 具体实现 略。。
|
||||
return apyAccounts.get(payId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
|
||||
|
||||
package in.egan.pay.demo.entity;
|
||||
|
||||
import in.egan.pay.common.bean.MsgType;
|
||||
|
||||
//import javax.persistence.*;
|
||||
|
||||
/**
|
||||
* 支付账户
|
||||
* @author: egan
|
||||
* @email egzosn@gmail.com
|
||||
* @date 2016/11/18 0:36
|
||||
*/
|
||||
//@Table(name = "apy_account")
|
||||
//@Entity
|
||||
public class ApyAccount {
|
||||
// 支付账号id
|
||||
// @Id
|
||||
// @GeneratedValue
|
||||
// @Column(name = "pay_id")
|
||||
private Integer payId;
|
||||
// 支付合作id,商户id,差不多是支付平台的账号或id
|
||||
// @Column(name = "partner")
|
||||
private String partner;
|
||||
// 应用id
|
||||
// @Column(name = "appid")
|
||||
private String appid;
|
||||
// 支付公钥,sign_type只有单一key时public_key与private_key相等,比如sign_type=MD5的情况
|
||||
private String publicKey;
|
||||
// 支付私钥
|
||||
// @Column(name = "private_key")
|
||||
private String privateKey;
|
||||
// 异步回调地址
|
||||
// @Column(name = "notify_url")
|
||||
private String notifyUrl;
|
||||
// 同步回调地址
|
||||
// @Column(name = "return_url")
|
||||
private String returnUrl;
|
||||
// 收款账号
|
||||
// @Column(name = "seller")
|
||||
private String seller;
|
||||
// 签名类型
|
||||
// @Column(name = "sign_type")
|
||||
private String signType;
|
||||
// 编码类型 枚举值,字符编码 utf-8,gbk等等
|
||||
// @Column(name = "input_charset")
|
||||
private String inputCharset;
|
||||
//支付类型,aliPay:支付宝,wxPay:微信, youdianPay: 友店微信,此处开发者自定义对应in.egan.pay.demo.entity.PayType枚举值
|
||||
// @Enumerated(EnumType.STRING)
|
||||
// @Column(name = "pay_type")
|
||||
private PayType payType;
|
||||
// 消息类型,text,xml,json
|
||||
// @Enumerated(EnumType.STRING)
|
||||
// @Column(name = "msg_type")
|
||||
private MsgType msgType;
|
||||
|
||||
public Integer getPayId() {
|
||||
return payId;
|
||||
}
|
||||
|
||||
public void setPayId(Integer payId) {
|
||||
this.payId = payId;
|
||||
}
|
||||
|
||||
public String getPartner() {
|
||||
return partner;
|
||||
}
|
||||
|
||||
public void setPartner(String partner) {
|
||||
this.partner = partner;
|
||||
}
|
||||
|
||||
public String getAppid() {
|
||||
return appid;
|
||||
}
|
||||
|
||||
public void setAppid(String appid) {
|
||||
this.appid = appid;
|
||||
}
|
||||
|
||||
public String getPublicKey() {
|
||||
return publicKey;
|
||||
}
|
||||
|
||||
public void setPublicKey(String publicKey) {
|
||||
this.publicKey = publicKey;
|
||||
}
|
||||
|
||||
public String getPrivateKey() {
|
||||
return privateKey;
|
||||
}
|
||||
|
||||
public void setPrivateKey(String privateKey) {
|
||||
this.privateKey = privateKey;
|
||||
}
|
||||
|
||||
public String getNotifyUrl() {
|
||||
return notifyUrl;
|
||||
}
|
||||
|
||||
public void setNotifyUrl(String notifyUrl) {
|
||||
this.notifyUrl = notifyUrl;
|
||||
}
|
||||
|
||||
public String getReturnUrl() {
|
||||
return returnUrl;
|
||||
}
|
||||
|
||||
public void setReturnUrl(String returnUrl) {
|
||||
this.returnUrl = returnUrl;
|
||||
}
|
||||
|
||||
public String getSeller() {
|
||||
return seller;
|
||||
}
|
||||
|
||||
public void setSeller(String seller) {
|
||||
this.seller = seller;
|
||||
}
|
||||
|
||||
public String getSignType() {
|
||||
return signType;
|
||||
}
|
||||
|
||||
public void setSignType(String signType) {
|
||||
this.signType = signType;
|
||||
}
|
||||
|
||||
public PayType getPayType() {
|
||||
return payType;
|
||||
}
|
||||
|
||||
public void setPayType(PayType payType) {
|
||||
this.payType = payType;
|
||||
}
|
||||
|
||||
public MsgType getMsgType() {
|
||||
return msgType;
|
||||
}
|
||||
|
||||
public void setMsgType(MsgType msgType) {
|
||||
this.msgType = msgType;
|
||||
}
|
||||
|
||||
public String getInputCharset() {
|
||||
return inputCharset;
|
||||
}
|
||||
|
||||
public void setInputCharset(String inputCharset) {
|
||||
this.inputCharset = inputCharset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ApyAccount{" +
|
||||
"payId=" + payId +
|
||||
", partner='" + partner + '\'' +
|
||||
", appid='" + appid + '\'' +
|
||||
", publicKey='" + publicKey + '\'' +
|
||||
", privateKey='" + privateKey + '\'' +
|
||||
", notifyUrl='" + notifyUrl + '\'' +
|
||||
", returnUrl='" + returnUrl + '\'' +
|
||||
", seller='" + seller + '\'' +
|
||||
", signType='" + signType + '\'' +
|
||||
", inputCharset='" + inputCharset + '\'' +
|
||||
", payType=" + payType +
|
||||
", msgType=" + msgType +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
109
pay-java-demo/src/main/java/in/egan/pay/demo/entity/PayType.java
Normal file
109
pay-java-demo/src/main/java/in/egan/pay/demo/entity/PayType.java
Normal file
@@ -0,0 +1,109 @@
|
||||
package in.egan.pay.demo.entity;
|
||||
|
||||
import in.egan.pay.ali.api.AliPayConfigStorage;
|
||||
import in.egan.pay.ali.api.AliPayService;
|
||||
import in.egan.pay.ali.bean.AliTransactionType;
|
||||
import in.egan.pay.common.api.PayService;
|
||||
import in.egan.pay.common.bean.BasePayType;
|
||||
import in.egan.pay.common.bean.TransactionType;
|
||||
import in.egan.pay.wx.api.WxPayConfigStorage;
|
||||
import in.egan.pay.wx.api.WxPayService;
|
||||
import in.egan.pay.wx.bean.WxTransactionType;
|
||||
import in.egan.pay.wx.youdian.api.WxYouDianPayConfigStorage;
|
||||
import in.egan.pay.wx.youdian.api.WxYouDianPayService;
|
||||
import in.egan.pay.wx.youdian.bean.YoudianTransactionType;
|
||||
|
||||
|
||||
/**
|
||||
* 支付类型
|
||||
* @author egan
|
||||
* @email egzosn@gmail.com
|
||||
* @date 2016/11/20 0:30
|
||||
*/
|
||||
public enum PayType implements BasePayType {
|
||||
|
||||
aliPay{
|
||||
@Override
|
||||
public PayService getPayService(ApyAccount apyAccount) {
|
||||
AliPayConfigStorage aliPayConfigStorage = new AliPayConfigStorage();
|
||||
aliPayConfigStorage.setPartner(apyAccount.getPartner());
|
||||
aliPayConfigStorage.setAliPublicKey(apyAccount.getPublicKey());
|
||||
aliPayConfigStorage.setKeyPrivate(apyAccount.getPrivateKey());
|
||||
aliPayConfigStorage.setNotifyUrl(apyAccount.getNotifyUrl());
|
||||
aliPayConfigStorage.setReturnUrl(apyAccount.getReturnUrl());
|
||||
aliPayConfigStorage.setSignType(apyAccount.getSignType());
|
||||
aliPayConfigStorage.setSeller(apyAccount.getSeller());
|
||||
aliPayConfigStorage.setPayType(apyAccount.getPayType().toString());
|
||||
aliPayConfigStorage.setMsgType(apyAccount.getMsgType());
|
||||
aliPayConfigStorage.setInputCharset(apyAccount.getInputCharset());
|
||||
return new AliPayService(aliPayConfigStorage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransactionType getTransactionType(String transactionType) {
|
||||
return AliTransactionType.valueOf(transactionType);
|
||||
}
|
||||
|
||||
|
||||
},wxPay {
|
||||
@Override
|
||||
public PayService getPayService(ApyAccount apyAccount) {
|
||||
WxPayConfigStorage wxPayConfigStorage = new WxPayConfigStorage();
|
||||
wxPayConfigStorage.setMchId(apyAccount.getPartner());
|
||||
wxPayConfigStorage.setAppSecret(apyAccount.getPublicKey());
|
||||
wxPayConfigStorage.setKeyPublic(apyAccount.getPublicKey());
|
||||
wxPayConfigStorage.setAppid(apyAccount.getAppid());
|
||||
wxPayConfigStorage.setKeyPrivate(apyAccount.getPrivateKey());
|
||||
wxPayConfigStorage.setNotifyUrl(apyAccount.getNotifyUrl());
|
||||
wxPayConfigStorage.setSignType(apyAccount.getSignType());
|
||||
wxPayConfigStorage.setPayType(apyAccount.getPayType().toString());
|
||||
wxPayConfigStorage.setMsgType(apyAccount.getMsgType());
|
||||
wxPayConfigStorage.setInputCharset(apyAccount.getInputCharset());
|
||||
return new WxPayService(wxPayConfigStorage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据支付类型获取交易类型
|
||||
* @param transactionType 类型值
|
||||
* @see WxTransactionType
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public TransactionType getTransactionType(String transactionType) {
|
||||
|
||||
return WxTransactionType.valueOf(transactionType);
|
||||
}
|
||||
},youdianPay {
|
||||
@Override
|
||||
public PayService getPayService(ApyAccount apyAccount) {
|
||||
// TODO 2017/1/23 14:12 author: egan 集群的话,友店可能会有bug。暂未测试集群环境
|
||||
WxYouDianPayConfigStorage wxPayConfigStorage = new WxYouDianPayConfigStorage();
|
||||
wxPayConfigStorage.setKeyPrivate(apyAccount.getPrivateKey());
|
||||
wxPayConfigStorage.setKeyPublic(apyAccount.getPublicKey());
|
||||
// wxPayConfigStorage.setNotifyUrl(apyAccount.getNotifyUrl());
|
||||
// wxPayConfigStorage.setReturnUrl(apyAccount.getReturnUrl());
|
||||
wxPayConfigStorage.setSignType(apyAccount.getSignType());
|
||||
wxPayConfigStorage.setPayType(apyAccount.getPayType().toString());
|
||||
wxPayConfigStorage.setMsgType(apyAccount.getMsgType());
|
||||
wxPayConfigStorage.setSeller(apyAccount.getSeller());
|
||||
wxPayConfigStorage.setInputCharset(apyAccount.getInputCharset());
|
||||
return new WxYouDianPayService(wxPayConfigStorage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据支付类型获取交易类型
|
||||
* @param transactionType 类型值
|
||||
* @see YoudianTransactionType
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public TransactionType getTransactionType(String transactionType) {
|
||||
|
||||
return YoudianTransactionType.valueOf(transactionType);
|
||||
}
|
||||
};
|
||||
|
||||
public abstract PayService getPayService(ApyAccount apyAccount);
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
|
||||
package in.egan.pay.demo.service;
|
||||
|
||||
import in.egan.pay.demo.dao.ApyAccountRepository;
|
||||
import in.egan.pay.demo.entity.ApyAccount;
|
||||
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
|
||||
import org.springframework.stereotype.Service;
|
||||
import javax.annotation.Resource;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author: egan
|
||||
* @email egzosn@gmail.com
|
||||
* @date 2016/11/18 1:11
|
||||
*/
|
||||
@Service
|
||||
public class ApyAccountService {
|
||||
|
||||
// @Resource
|
||||
private ApyAccountRepository dao;
|
||||
|
||||
@Resource
|
||||
private AutowireCapableBeanFactory spring;
|
||||
|
||||
//缓存
|
||||
private final static Map<Integer, PayResponse> payResponses = new HashMap<Integer, PayResponse>();
|
||||
|
||||
/**
|
||||
* 这里简单初始化,引入orm等框架之后可自行删除
|
||||
*/
|
||||
{
|
||||
|
||||
dao = new ApyAccountRepository();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取支付响应
|
||||
* @param id 账户id
|
||||
* @return
|
||||
*/
|
||||
public PayResponse getPayResponse(Integer id) {
|
||||
|
||||
PayResponse payResponse = payResponses.get(id);
|
||||
if (payResponse == null) {
|
||||
ApyAccount apyAccount = dao.findByPayId(id);
|
||||
if (apyAccount == null) {
|
||||
throw new IllegalArgumentException ("无法查询");
|
||||
}
|
||||
payResponse = new PayResponse();
|
||||
spring.autowireBean(payResponse);
|
||||
payResponse.init(apyAccount);
|
||||
payResponses.put(id, payResponse);
|
||||
// 查询
|
||||
}
|
||||
return payResponse;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
|
||||
|
||||
package in.egan.pay.demo.service;
|
||||
|
||||
import in.egan.pay.demo.entity.ApyAccount;
|
||||
import in.egan.pay.demo.entity.PayType;
|
||||
import in.egan.pay.demo.service.handler.AliPayMessageHandler;
|
||||
import in.egan.pay.demo.service.handler.FuiouPayMessageHandler;
|
||||
import in.egan.pay.demo.service.handler.WxPayMessageHandler;
|
||||
import in.egan.pay.demo.service.handler.YouDianPayMessageHandler;
|
||||
import in.egan.pay.demo.service.interceptor.AliPayMessageInterceptor;
|
||||
import in.egan.pay.common.api.PayConfigStorage;
|
||||
import in.egan.pay.common.api.PayMessageHandler;
|
||||
import in.egan.pay.common.api.PayMessageRouter;
|
||||
import in.egan.pay.common.api.PayService;
|
||||
import in.egan.pay.common.bean.MsgType;
|
||||
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 支付响应对象
|
||||
* @author: egan
|
||||
* @email egzosn@gmail.com
|
||||
* @date 2016/11/18 0:34
|
||||
*/
|
||||
public class PayResponse {
|
||||
|
||||
@Resource
|
||||
private AutowireCapableBeanFactory spring;
|
||||
|
||||
private PayConfigStorage storage;
|
||||
|
||||
private PayService service;
|
||||
|
||||
private PayMessageRouter router;
|
||||
|
||||
public PayResponse() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化支付配置
|
||||
* @param apyAccount 账户信息
|
||||
* @see ApyAccount 对应表结构详情--》 /pay-java-demo/resources/apy_account.sql
|
||||
*/
|
||||
public void init(ApyAccount apyAccount) {
|
||||
//根据不同的账户类型 初始化支付配置
|
||||
this.service = apyAccount.getPayType().getPayService(apyAccount);
|
||||
this.storage = service.getPayConfigStorage();
|
||||
|
||||
buildRouter(apyAccount.getPayId());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 配置路由
|
||||
* @param payId 指定账户id,用户多微信支付多支付宝支付
|
||||
*/
|
||||
private void buildRouter(Integer payId) {
|
||||
router = new PayMessageRouter(this.service);
|
||||
router
|
||||
.rule()
|
||||
.async(false)
|
||||
.msgType(MsgType.text.name()) //消息类型
|
||||
.event(PayType.aliPay.name()) //支付账户事件类型
|
||||
.interceptor(new AliPayMessageInterceptor(payId)) //拦截器
|
||||
.handler(autowire(new AliPayMessageHandler(payId))) //处理器
|
||||
.end()
|
||||
.rule()
|
||||
.async(false)
|
||||
.msgType(MsgType.xml.name())
|
||||
.event(PayType.wxPay.name())
|
||||
.handler(autowire(new WxPayMessageHandler(payId)))
|
||||
.end()
|
||||
.rule()
|
||||
.async(false)
|
||||
.msgType(MsgType.json.name())
|
||||
.event(PayType.youdianPay.name())
|
||||
.handler(autowire(new YouDianPayMessageHandler(payId)))
|
||||
.end()
|
||||
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
private PayMessageHandler autowire(PayMessageHandler handler) {
|
||||
spring.autowireBean(handler);
|
||||
return handler;
|
||||
}
|
||||
|
||||
public PayConfigStorage getStorage() {
|
||||
return storage;
|
||||
}
|
||||
|
||||
public PayService getService() {
|
||||
return service;
|
||||
}
|
||||
|
||||
public PayMessageRouter getRouter() {
|
||||
return router;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package in.egan.pay.demo.service.handler;
|
||||
|
||||
import in.egan.pay.common.api.PayService;
|
||||
import in.egan.pay.common.bean.PayMessage;
|
||||
import in.egan.pay.common.bean.PayOutMessage;
|
||||
import in.egan.pay.common.exception.PayErrorException;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 支付宝支付回调处理器
|
||||
* Created by ZaoSheng on 2016/6/1.
|
||||
*
|
||||
*/
|
||||
public class AliPayMessageHandler extends BasePayMessageHandler {
|
||||
|
||||
|
||||
public AliPayMessageHandler(Integer payId) {
|
||||
super(payId);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public PayOutMessage handle(PayMessage payMessage, Map<String, Object> context, PayService payService) throws PayErrorException {
|
||||
//交易状态
|
||||
String trade_status = null;
|
||||
try {
|
||||
trade_status = new String(payMessage.getPayMessage().get("trade_status").getBytes("ISO-8859-1"),"UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if(trade_status.equals("TRADE_FINISHED")){
|
||||
|
||||
//判断该笔订单是否在商户网站中已经做过处理
|
||||
//如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
|
||||
//如果有做过处理,不执行商户的业务程序
|
||||
//注意:
|
||||
//退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知
|
||||
} else if (trade_status.equals("TRADE_SUCCESS")){
|
||||
|
||||
//判断该笔订单是否在商户网站中已经做过处理
|
||||
//如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
|
||||
//如果有做过处理,不执行商户的业务程序
|
||||
//注意:
|
||||
//付款完成后,支付宝系统发送该交易状态通知
|
||||
|
||||
|
||||
}else if (trade_status.equals("TRADE_SUCCESS")){
|
||||
// 交易创建
|
||||
}
|
||||
|
||||
return payService.getPayOutMessage("success", "成功");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package in.egan.pay.demo.service.handler;
|
||||
|
||||
import in.egan.pay.common.api.PayMessageHandler;
|
||||
|
||||
/**
|
||||
*
|
||||
* Created by ZaoSheng on 2016/6/1.
|
||||
*/
|
||||
public abstract class BasePayMessageHandler implements PayMessageHandler {
|
||||
//支付账户id
|
||||
private Integer payId;
|
||||
|
||||
public BasePayMessageHandler(Integer payId) {
|
||||
this.payId = payId;
|
||||
}
|
||||
|
||||
public Integer getPayId() {
|
||||
return payId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package in.egan.pay.demo.service.handler;
|
||||
|
||||
import in.egan.pay.common.api.PayService;
|
||||
import in.egan.pay.common.bean.PayMessage;
|
||||
import in.egan.pay.common.bean.PayOutMessage;
|
||||
import in.egan.pay.common.exception.PayErrorException;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Fuzx
|
||||
* @create 2017 2017/1/24 0024
|
||||
*/
|
||||
public class FuiouPayMessageHandler extends BasePayMessageHandler {
|
||||
|
||||
|
||||
|
||||
|
||||
public FuiouPayMessageHandler(Integer payId) {
|
||||
super(payId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PayOutMessage handle(PayMessage payMessage, Map<String, Object> context, PayService payService) throws PayErrorException {
|
||||
//交易状态
|
||||
if ("0000".equals(payMessage.getPayMessage().get("order_pay_code"))){
|
||||
/////这里进行成功的处理
|
||||
|
||||
return PayOutMessage.JSON().content("order_pay_error","成功").build();
|
||||
}
|
||||
|
||||
return PayOutMessage.JSON().content("order_pay_error",payMessage.getPayMessage().get("order_pay_error")).build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package in.egan.pay.demo.service.handler;
|
||||
|
||||
import in.egan.pay.common.api.PayService;
|
||||
import in.egan.pay.common.bean.PayMessage;
|
||||
import in.egan.pay.common.bean.PayOutMessage;
|
||||
import in.egan.pay.common.exception.PayErrorException;
|
||||
import in.egan.pay.demo.service.handler.BasePayMessageHandler;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 微信支付回调处理器
|
||||
* Created by ZaoSheng on 2016/6/1.
|
||||
*/
|
||||
public class WxPayMessageHandler extends BasePayMessageHandler {
|
||||
|
||||
|
||||
|
||||
|
||||
public WxPayMessageHandler(Integer payId) {
|
||||
super(payId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PayOutMessage handle(PayMessage payMessage, Map<String, Object> context, PayService payService) throws PayErrorException {
|
||||
//交易状态
|
||||
if ("SUCCESS".equals(payMessage.getPayMessage().get("result_code"))){
|
||||
/////这里进行成功的处理
|
||||
|
||||
return payService.getPayOutMessage("SUCCESS", "OK");
|
||||
}
|
||||
|
||||
return payService.getPayOutMessage("FAIL", "失败");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package in.egan.pay.demo.service.handler;
|
||||
|
||||
import in.egan.pay.common.api.PayService;
|
||||
import in.egan.pay.common.bean.PayMessage;
|
||||
import in.egan.pay.common.bean.PayOutMessage;
|
||||
import in.egan.pay.common.exception.PayErrorException;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Fuzx
|
||||
* @create 2017 2017/1/24 0024
|
||||
*/
|
||||
public class YouDianPayMessageHandler extends BasePayMessageHandler {
|
||||
|
||||
|
||||
|
||||
|
||||
public YouDianPayMessageHandler(Integer payId) {
|
||||
super(payId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PayOutMessage handle(PayMessage payMessage, Map<String, Object> context, PayService payService) throws PayErrorException {
|
||||
//交易状态
|
||||
if ("0000".equals(payMessage.getPayMessage().get("order_pay_code"))){
|
||||
/////这里进行成功的处理
|
||||
|
||||
return PayOutMessage.JSON().content("order_pay_error","成功").build();
|
||||
}
|
||||
|
||||
return PayOutMessage.JSON().content("order_pay_error",payMessage.getPayMessage().get("order_pay_error")).build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
|
||||
package in.egan.pay.demo.service.interceptor;
|
||||
|
||||
import in.egan.pay.common.api.PayMessageHandler;
|
||||
import in.egan.pay.common.api.PayMessageInterceptor;
|
||||
import in.egan.pay.common.api.PayService;
|
||||
import in.egan.pay.common.bean.PayMessage;
|
||||
import in.egan.pay.common.exception.PayErrorException;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 支付宝回调信息拦截器
|
||||
* @author: egan
|
||||
* @email egzosn@gmail.com
|
||||
* @date 2017/1/18 19:28
|
||||
*/
|
||||
public class AliPayMessageInterceptor implements PayMessageInterceptor {
|
||||
|
||||
//支付账户id
|
||||
private Integer payId;
|
||||
public AliPayMessageInterceptor(Integer payId) {
|
||||
|
||||
this.payId = payId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 拦截支付消息
|
||||
*
|
||||
* @param payMessage 支付回调消息
|
||||
* @param context 上下文,如果handler或interceptor之间有信息要传递,可以用这个
|
||||
* @param payService
|
||||
* @return true代表OK,false代表不OK并直接中断对应的支付处理器
|
||||
* @see PayMessageHandler 支付处理器
|
||||
*/
|
||||
@Override
|
||||
public boolean intercept(PayMessage payMessage, Map<String, Object> context, PayService payService) throws PayErrorException {
|
||||
|
||||
//这里进行拦截器处理,自行实现
|
||||
return true;
|
||||
}
|
||||
}
|
||||
18
pay-java-demo/src/main/resources/applicationContext.xml
Normal file
18
pay-java-demo/src/main/resources/applicationContext.xml
Normal file
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/context
|
||||
http://www.springframework.org/schema/context/spring-context.xsd"
|
||||
>
|
||||
|
||||
<!-- 使用annotation注解的方式时,需要添加上此行配置 -->
|
||||
<context:annotation-config />
|
||||
|
||||
<context:component-scan base-package="in.egan.pay.demo" />
|
||||
|
||||
|
||||
|
||||
</beans>
|
||||
31
pay-java-demo/src/main/resources/apy_account.sql
Normal file
31
pay-java-demo/src/main/resources/apy_account.sql
Normal file
@@ -0,0 +1,31 @@
|
||||
|
||||
/*Table structure for table `apy_account` */
|
||||
|
||||
DROP TABLE IF EXISTS `apy_account`;
|
||||
|
||||
CREATE TABLE `apy_account` (
|
||||
`pay_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '支付账号id',
|
||||
`partner` varchar(32) DEFAULT NULL COMMENT '支付合作id,商户id,差不多是支付平台的账号或id',
|
||||
`appid` varchar(32) DEFAULT NULL COMMENT '应用id',
|
||||
`public_key` varchar(1204) DEFAULT NULL COMMENT '支付公钥,sign_type只有单一key时public_key与private_key相等,比如sign_type=MD5的情况',
|
||||
`private_key` varchar(2048) DEFAULT NULL COMMENT '支付私钥',
|
||||
`notify_url` varchar(1024) DEFAULT NULL COMMENT '异步回调地址',
|
||||
`return_url` varchar(1024) DEFAULT NULL COMMENT '同步回调地址',
|
||||
`seller` varchar(256) DEFAULT NULL COMMENT '收款账号, 针对支付宝',
|
||||
`sign_type` varchar(16) DEFAULT NULL COMMENT '签名类型',
|
||||
`input_charset` varchar(16) DEFAULT NULL COMMENT '枚举值,字符编码 utf-8,gbk等等',
|
||||
`pay_type` char(16) DEFAULT NULL COMMENT '支付类型,aliPay:支付宝,wxPay:微信, youdianPay: 友店微信,此处开发者自定义对应in.egan.pay.demo.entity.PayType枚举值',
|
||||
`msg_type` char(8) DEFAULT NULL COMMENT '消息类型,text,xml,json',
|
||||
`create_by` char(32) DEFAULT NULL COMMENT '创建人',
|
||||
`create_time` timestamp NULL DEFAULT NULL COMMENT '创建时间',
|
||||
PRIMARY KEY (`pay_id`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
|
||||
|
||||
/*Data for the table `apy_account` */
|
||||
|
||||
insert into `apy_account`(`pay_id`,`partner`,`appid`,`public_key`,`private_key`,`notify_url`,`return_url`,`seller`,`sign_type`,`input_charset`,`pay_type`,`msg_type`,`create_by`,`create_time`) values
|
||||
(1,'12******01','wxa**********ba9e9','48gf0iwuhr***********r9weh9eiut9','48gf0iwuhr***********r9weh9eiut9','http://pay.egan.in/payBack2.json','同步回调地址','','MD5','utf-8','wxPay','xml','egan','2017-01-20 17:07:48'),
|
||||
(2,'20889119449*****','','MIGfMA0GCSqGSIb3DQEB*********gmLCUYuLkxpLQIDAQAB','IqZg51Vx8BvyypnIfKgw=*********MIICdwIBADANBgkqhkiG9w0BAQE','http://pay.egan.in/payBack3.json','同步回调地址','egzosn@gmail.com','RSA','utf-8','aliPay','text','egan','2017-01-20 17:11:46'),
|
||||
|
||||
|
||||
|
||||
34
pay-java-demo/src/main/resources/mvc-servlet-context.xml
Normal file
34
pay-java-demo/src/main/resources/mvc-servlet-context.xml
Normal file
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:mvc="http://www.springframework.org/schema/mvc"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/mvc
|
||||
http://www.springframework.org/schema/mvc/spring-mvc.xsd
|
||||
http://www.springframework.org/schema/context
|
||||
http://www.springframework.org/schema/context/spring-context.xsd
|
||||
">
|
||||
|
||||
<!-- 使用annotation注解的方式时,需要添加上此行配置 -->
|
||||
<context:annotation-config/>
|
||||
|
||||
<!-- 只扫描控制器Action -->
|
||||
<context:component-scan base-package="in.egan.pay.demo.controller" />
|
||||
|
||||
<!-- MVC 注解 -->
|
||||
<mvc:annotation-driven>
|
||||
<!-- <mvc:message-converters >
|
||||
<!– 配置Fastjson支持 –>
|
||||
<bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter4">
|
||||
|
||||
</bean>
|
||||
</mvc:message-converters>-->
|
||||
</mvc:annotation-driven>
|
||||
|
||||
<!-- 静态资源,当找不到对应的处理时,调用这个 -->
|
||||
<mvc:default-servlet-handler/>
|
||||
|
||||
|
||||
</beans>
|
||||
37
pay-java-demo/src/main/webapp/WEB-INF/web.xml
Normal file
37
pay-java-demo/src/main/webapp/WEB-INF/web.xml
Normal file
@@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
|
||||
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
|
||||
version="3.0">
|
||||
<welcome-file-list>
|
||||
<welcome-file>index.html</welcome-file>
|
||||
</welcome-file-list>
|
||||
<context-param>
|
||||
<description>Spring 配置文件</description>
|
||||
<param-name>contextConfigLocation</param-name>
|
||||
<param-value>
|
||||
classpath:applicationContext.xml
|
||||
</param-value>
|
||||
</context-param>
|
||||
<servlet>
|
||||
<servlet-name>spring</servlet-name>
|
||||
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
|
||||
<init-param>
|
||||
<param-name>contextConfigLocation</param-name>
|
||||
<param-value>classpath:mvc-servlet-context.xml</param-value>
|
||||
</init-param>
|
||||
<load-on-startup>1</load-on-startup>
|
||||
</servlet>
|
||||
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>spring</servlet-name>
|
||||
<url-pattern>/*</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<listener>
|
||||
<description>Spring 监听器</description>
|
||||
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
|
||||
</listener>
|
||||
</web-app>
|
||||
120
pay-java-demo/src/main/webapp/index.html
Normal file
120
pay-java-demo/src/main/webapp/index.html
Normal file
@@ -0,0 +1,120 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>TEST</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
账户信息添加用于下面测试
|
||||
<div>
|
||||
<form id="form">
|
||||
账户id<input type="text" name="payId">
|
||||
<br>
|
||||
支付合作id<input type="text" name="partner">
|
||||
<br>
|
||||
应用id<input type="text" name="appid">
|
||||
<br>
|
||||
支付公钥<input type="text" name="publicKey"><b>如签名类型为MD5时,当前的值与支付私钥想等</b>
|
||||
<br>
|
||||
支付私钥<input type="text" name="privateKey">
|
||||
<br>
|
||||
异步回调地址<input type="text" name="notifyUrl"><b>友店支付用不到此参数,在友店管理端进行配置</b>
|
||||
<br>
|
||||
同步回调地址<input type="text" name="returnUrl"><b>同上</b>
|
||||
<br>
|
||||
收款账号(即时付款填写支付合作id)<input type="text" name="seller"><b>针对支付宝</b>
|
||||
<br/>
|
||||
签名类型<select name="signType">
|
||||
<option>MD5</option>
|
||||
<option>RSA</option>
|
||||
</select>
|
||||
<br>
|
||||
编码类型(建议UTF-8)<input type="text" name="inputCharset">
|
||||
<br>
|
||||
支付账户类型 <select name="payType">
|
||||
<option value="aliPay">aliPay</option>
|
||||
<option value="wxPay">wxPay</option>
|
||||
<option value="youdianPay">youdianPay</option>
|
||||
</select><b>此处为开发者自定义,详情请查看 in.egan.pay.demo.entity.PayType</b>
|
||||
<br>
|
||||
消息类型 <select name="msgType">
|
||||
<option>text</option>
|
||||
<option>xml</option>
|
||||
<option>json</option>
|
||||
</select>
|
||||
<br>
|
||||
</form>
|
||||
<button id="submit">提交</button>
|
||||
</div>
|
||||
|
||||
<br/>
|
||||
<div>各个支付对应的<b>交易类型</b>可自行查看对应的官方文档,本项目已实现几种交易类型,对应各个支付类型的<code>in.egan.pay.common.bean.TransactionType</code>具体实现</div>
|
||||
<div>支付宝(<code>in.egan.pay.ali.bean.AliTransactionType</code>): 即时付款=DIRECT , 移动支付=APP , 手机网站支付=WAP</div>
|
||||
<div>微信(<code>in.egan.pay.wx.bean.WxTransactionType</code>): 公众号支付=JSAPI , 移动支付=APP , 扫码付=NATIVE</div>
|
||||
<div>友店微信(<code>in.egan.pay.wx.youdian.bean.YoudianTransactionType</code>): 扫码付=NATIVE</div>
|
||||
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
APP提交(返回对应的json,具体实现,app端demo暂时未实现)
|
||||
<form action="getOrderInfo" target="_blank">
|
||||
账户id<input type="text" name="payId">
|
||||
<br>
|
||||
金额<input type="text" name="price">
|
||||
<br>
|
||||
交易类型<input type="text" name="transactionType" value="APP" readonly>
|
||||
<br>
|
||||
<input type="submit" value="提交">
|
||||
</form>
|
||||
|
||||
<br>
|
||||
普通web提交
|
||||
<form action="toPay.html" target="_blank">
|
||||
账户id<input type="text" name="payId">
|
||||
<br>
|
||||
金额<input type="text" name="price">
|
||||
<br>
|
||||
交易类型<input type="text" name="transactionType">
|
||||
<br>
|
||||
<input type="submit" value="提交">
|
||||
</form>
|
||||
|
||||
<br>
|
||||
二维码
|
||||
<form action="toQrPay.jpg" target="_blank">
|
||||
账户id<input type="text" name="payId">
|
||||
<br>
|
||||
金额<input type="text" name="price">
|
||||
<br>
|
||||
交易类型<input type="text" name="transactionType">
|
||||
<br>
|
||||
<input type="submit" value="提交">
|
||||
</form>
|
||||
<script src="jquery-3.1.1.min.js"></script>
|
||||
<script>
|
||||
$(function ($) {
|
||||
$("#submit").click(function () {
|
||||
$.ajax({
|
||||
url : "add",
|
||||
type : "post",
|
||||
data : $("#form").serialize(),
|
||||
dataType : 'json',
|
||||
success : function(data) {
|
||||
if (data.code == 0){
|
||||
alert("保存成功");
|
||||
return;
|
||||
}
|
||||
alert("保存失败");
|
||||
},
|
||||
error : function(edata) {
|
||||
alert("服务器异常")
|
||||
}
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
4
pay-java-demo/src/main/webapp/jquery-3.1.1.min.js
vendored
Normal file
4
pay-java-demo/src/main/webapp/jquery-3.1.1.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user