mirror of
https://gitee.com/egzosn/pay-java-parent.git
synced 2026-06-08 02:17:20 +08:00
Merge branches 'develop-Actinia' and 'master' of https://git.oschina.net/egzosn/pay-java-parent into develop-Actinia
# Conflicts: # README.md
This commit is contained in:
12
README.md
12
README.md
@@ -1,21 +1,25 @@
|
||||
|
||||
#pay-java-parent
|
||||
|
||||
## 整合支付模块
|
||||
##整合支付模块(微信支付,支付宝)
|
||||
|
||||
声明: 本项目最初想法自 https://github.com/chanjarster/weixin-java-tools, 15年1月左右关注chanjarster/weixin-java-tools,并将其回调处理修改并进行使用。
|
||||
|
||||
开发版 https://git.oschina.net/egzosn/pay-java-parent/tree/develop
|
||||
|
||||
##### 详细文档请看 [wiki](https://gitee.com/egzosn/pay-java-parent/wikis/Home)。
|
||||
|
||||
### 特性
|
||||
|
||||
|
||||
|
||||
1. 不依赖任何 mvc 框架
|
||||
2. 也不依赖 servlet,仅仅作为工具使用,可轻松嵌入到任何系统里(项目例子利用spring mvc的 @PathVariable进行,推荐使用类似的框架)
|
||||
3. 支付请求调用支持HTTP和异步、支持http代理
|
||||
4. 控制层统一异常处理
|
||||
5. LogBack日志记录
|
||||
6. 简单快速完成支付模块的开发
|
||||
7. 支持多种支付类型多支付账户扩展
|
||||
7. 支持多种支付类型多支付账户扩展(目前已支持微信支付,支付宝支付,友店支付)
|
||||
|
||||
### 本项目包含 3 个部分:
|
||||
|
||||
@@ -55,8 +59,8 @@
|
||||
|
||||
###### 单一支付教程
|
||||
|
||||
[基础模块支付宝微信讲解](pay-java-parent/wikis/Home)
|
||||
|
||||
[基础模块支付宝微信讲解](https://gitee.com/egzosn/pay-java-parent/wikis/Home)
|
||||
|
||||
[友店微信](pay-java-wx-youdian?dir=1&filepath=pay-java-youdian)
|
||||
[富友](pay-java-fuiou?dir=1&filepath=pay-java-fuiou)
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ public class PayTest {
|
||||
AliPayConfigStorage aliPayConfigStorage = new AliPayConfigStorage();
|
||||
aliPayConfigStorage.setPid("合作者id");
|
||||
aliPayConfigStorage.setAppId("应用id");
|
||||
aliPayConfigStorage.setAliPublicKey("支付宝公钥");
|
||||
aliPayConfigStorage.setKeyPublic("支付宝公钥");
|
||||
aliPayConfigStorage.setKeyPrivate("应用私钥");
|
||||
aliPayConfigStorage.setNotifyUrl("异步回调地址");
|
||||
aliPayConfigStorage.setReturnUrl("同步回调地址");
|
||||
|
||||
@@ -190,4 +190,23 @@ public class PayOrder {
|
||||
public void setOpenid(String openid) {
|
||||
this.openid = openid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PayOrder{" +
|
||||
"subject='" + subject + '\'' +
|
||||
", body='" + body + '\'' +
|
||||
", price=" + price +
|
||||
", outTradeNo='" + outTradeNo + '\'' +
|
||||
", bankType='" + bankType + '\'' +
|
||||
", deviceInfo='" + deviceInfo + '\'' +
|
||||
", spbillCreateIp='" + spbillCreateIp + '\'' +
|
||||
", authCode='" + authCode + '\'' +
|
||||
", wapUrl='" + wapUrl + '\'' +
|
||||
", wapName='" + wapName + '\'' +
|
||||
", openid='" + openid + '\'' +
|
||||
", transactionType=" + transactionType +
|
||||
", curType=" + curType +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,9 +153,10 @@ public class Base64 {
|
||||
Objects.requireNonNull(lineSeparator);
|
||||
int[] base64 = Decoder.fromBase64;
|
||||
for (byte b : lineSeparator) {
|
||||
if (base64[b & 0xff] != -1)
|
||||
if (base64[b & 0xff] != -1){
|
||||
throw new IllegalArgumentException(
|
||||
"Illegal base64 line separator character 0x" + Integer.toString(b, 16));
|
||||
}
|
||||
}
|
||||
if (lineLength <= 0) {
|
||||
return Encoder.RFC4648;
|
||||
@@ -264,8 +265,9 @@ public class Base64 {
|
||||
int n = srclen % 3;
|
||||
len = 4 * (srclen / 3) + (n == 0 ? 0 : n + 1);
|
||||
}
|
||||
if (linemax > 0) // line separators
|
||||
if (linemax > 0) { // line separators
|
||||
len += (len - 1) / linemax * newline.length;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
@@ -283,8 +285,9 @@ public class Base64 {
|
||||
int len = outLength(src.length); // dst array size
|
||||
byte[] dst = new byte[len];
|
||||
int ret = encode0(src, 0, src.length, dst);
|
||||
if (ret != dst.length)
|
||||
if (ret != dst.length) {
|
||||
return Arrays.copyOf(dst, ret);
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
@@ -367,8 +370,9 @@ public class Base64 {
|
||||
buffer.get(src);
|
||||
ret = encode0(src, 0, src.length, dst);
|
||||
}
|
||||
if (ret != dst.length)
|
||||
if (ret != dst.length) {
|
||||
dst = Arrays.copyOf(dst, ret);
|
||||
}
|
||||
return ByteBuffer.wrap(dst);
|
||||
}
|
||||
|
||||
@@ -415,8 +419,9 @@ public class Base64 {
|
||||
int sp = off;
|
||||
int slen = (end - off) / 3 * 3;
|
||||
int sl = off + slen;
|
||||
if (linemax > 0 && slen > linemax / 4 * 3)
|
||||
if (linemax > 0 && slen > linemax / 4 * 3){
|
||||
slen = linemax / 4 * 3;
|
||||
}
|
||||
int dp = 0;
|
||||
while (sp < sl) {
|
||||
int sl0 = Math.min(sp + slen, sl);
|
||||
@@ -507,8 +512,9 @@ public class Base64 {
|
||||
private static final int[] fromBase64 = new int[256];
|
||||
static {
|
||||
Arrays.fill(fromBase64, -1);
|
||||
for (int i = 0; i < Encoder.toBase64.length; i++)
|
||||
for (int i = 0; i < Encoder.toBase64.length; i++){
|
||||
fromBase64[Encoder.toBase64[i]] = i;
|
||||
}
|
||||
fromBase64['='] = -2;
|
||||
}
|
||||
|
||||
@@ -520,8 +526,9 @@ public class Base64 {
|
||||
|
||||
static {
|
||||
Arrays.fill(fromBase64URL, -1);
|
||||
for (int i = 0; i < Encoder.toBase64URL.length; i++)
|
||||
for (int i = 0; i < Encoder.toBase64URL.length; i++){
|
||||
fromBase64URL[Encoder.toBase64URL[i]] = i;
|
||||
}
|
||||
fromBase64URL['='] = -2;
|
||||
}
|
||||
|
||||
@@ -568,6 +575,9 @@ public class Base64 {
|
||||
* if {@code src} is not in valid Base64 scheme
|
||||
*/
|
||||
public byte[] decode(String src) {
|
||||
if (null != src){
|
||||
src = src.replaceAll("[\r\n]", "");
|
||||
}
|
||||
return decode(src.getBytes(StandardCharsets.ISO_8859_1));
|
||||
}
|
||||
|
||||
@@ -673,11 +683,13 @@ public class Base64 {
|
||||
int[] base64 = isURL ? fromBase64URL : fromBase64;
|
||||
int paddings = 0;
|
||||
int len = sl - sp;
|
||||
if (len == 0)
|
||||
if (len == 0){
|
||||
return 0;
|
||||
}
|
||||
if (len < 2) {
|
||||
if (isMIME && base64[0] == -1)
|
||||
if (isMIME && base64[0] == -1){
|
||||
return 0;
|
||||
}
|
||||
throw new IllegalArgumentException(
|
||||
"Input byte[] should at least have 2 bytes for base64 bytes");
|
||||
}
|
||||
@@ -698,12 +710,14 @@ public class Base64 {
|
||||
} else {
|
||||
if (src[sl - 1] == '=') {
|
||||
paddings++;
|
||||
if (src[sl - 2] == '=')
|
||||
if (src[sl - 2] == '=') {
|
||||
paddings++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (paddings == 0 && (len & 0x3) != 0)
|
||||
if (paddings == 0 && (len & 0x3) != 0) {
|
||||
paddings = 4 - (len & 0x3);
|
||||
}
|
||||
return 3 * ((len + 3) / 4) - paddings;
|
||||
}
|
||||
|
||||
@@ -728,12 +742,14 @@ public class Base64 {
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (isMIME) // skip if for rfc2045
|
||||
if (isMIME){ // skip if for rfc2045
|
||||
continue;
|
||||
else
|
||||
}
|
||||
else{
|
||||
throw new IllegalArgumentException(
|
||||
"Illegal base64 character " +
|
||||
Integer.toString(src[sp - 1], 16));
|
||||
}
|
||||
}
|
||||
bits |= (b << shiftto);
|
||||
shiftto -= 6;
|
||||
@@ -759,8 +775,9 @@ public class Base64 {
|
||||
// anything left is invalid, if is not MIME.
|
||||
// if MIME, ignore all non-base64 character
|
||||
while (sp < sl) {
|
||||
if (isMIME && base64[src[sp++]] < 0)
|
||||
if (isMIME && base64[src[sp++]] < 0) {
|
||||
continue;
|
||||
}
|
||||
throw new IllegalArgumentException(
|
||||
"Input byte array has incorrect ending byte at " + sp);
|
||||
}
|
||||
@@ -808,12 +825,15 @@ public class Base64 {
|
||||
|
||||
@Override
|
||||
public void write(byte[] b, int off, int len) throws IOException {
|
||||
if (closed)
|
||||
if (closed) {
|
||||
throw new IOException("Stream is closed");
|
||||
if (off < 0 || len < 0 || off + len > b.length)
|
||||
}
|
||||
if (off < 0 || len < 0 || off + len > b.length) {
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
if (len == 0)
|
||||
}
|
||||
if (len == 0) {
|
||||
return;
|
||||
}
|
||||
if (leftover != 0) {
|
||||
if (leftover == 1) {
|
||||
b1 = b[off++] & 0xff;
|
||||
@@ -911,17 +931,21 @@ public class Base64 {
|
||||
|
||||
@Override
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
if (closed)
|
||||
if (closed) {
|
||||
throw new IOException("Stream is closed");
|
||||
if (eof && nextout < 0) // eof and no leftover
|
||||
}
|
||||
if (eof && nextout < 0) { // eof and no leftover
|
||||
return -1;
|
||||
if (off < 0 || len < 0 || len > b.length - off)
|
||||
}
|
||||
if (off < 0 || len < 0 || len > b.length - off) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
int oldOff = off;
|
||||
if (nextout >= 0) { // leftover output byte(s) in bits buf
|
||||
do {
|
||||
if (len == 0)
|
||||
if (len == 0) {
|
||||
return off - oldOff;
|
||||
}
|
||||
b[off++] = (byte)(bits >> nextout);
|
||||
len--;
|
||||
nextout -= 8;
|
||||
@@ -933,8 +957,9 @@ public class Base64 {
|
||||
if (v == -1) {
|
||||
eof = true;
|
||||
if (nextin != 18) {
|
||||
if (nextin == 12)
|
||||
if (nextin == 12) {
|
||||
throw new IOException("Base64 stream has one un-decoded dangling byte.");
|
||||
}
|
||||
// treat ending xx/xxx without padding character legal.
|
||||
// same logic as v == '=' below
|
||||
b[off++] = (byte)(bits >> (16));
|
||||
@@ -948,10 +973,11 @@ public class Base64 {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (off == oldOff)
|
||||
if (off == oldOff) {
|
||||
return -1;
|
||||
else
|
||||
}else {
|
||||
return off - oldOff;
|
||||
}
|
||||
}
|
||||
if (v == '=') { // padding byte(s)
|
||||
// = shiftto==18 unnecessary padding
|
||||
@@ -976,11 +1002,12 @@ public class Base64 {
|
||||
break;
|
||||
}
|
||||
if ((v = base64[v]) == -1) {
|
||||
if (isMIME) // skip if for rfc2045
|
||||
if (isMIME) { // skip if for rfc2045
|
||||
continue;
|
||||
else
|
||||
}else {
|
||||
throw new IOException("Illegal base64 character " +
|
||||
Integer.toString(v, 16));
|
||||
}
|
||||
}
|
||||
bits |= (v << nextin);
|
||||
if (nextin == 0) {
|
||||
@@ -1004,8 +1031,9 @@ public class Base64 {
|
||||
|
||||
@Override
|
||||
public int available() throws IOException {
|
||||
if (closed)
|
||||
if (closed) {
|
||||
throw new IOException("Stream is closed");
|
||||
}
|
||||
return is.available(); // TBD:
|
||||
}
|
||||
|
||||
|
||||
@@ -51,8 +51,8 @@ public class ApyAccountRepository {
|
||||
apyAccount2.setPartner("1469188802");
|
||||
apyAccount2.setAppid("wx3344f4aed352deae");
|
||||
// TODO 2017/2/9 16:20 author: egan sign_type只有单一key时public_key与private_key相等,比如sign_type=MD5的情况
|
||||
apyAccount2.setPublicKey("991ded0800933ccf8736ab4f7fc61095");
|
||||
apyAccount2.setPrivateKey("991ded0800933ccf8736ab4f7fc61095");
|
||||
apyAccount2.setPublicKey("991ded080***************f7fc61095");
|
||||
apyAccount2.setPrivateKey("991ded080***************f7fc61095");
|
||||
apyAccount2.setNotifyUrl("http://pay.egzosn.com/payBack2.json");
|
||||
// 无需同步回调可不填
|
||||
apyAccount2.setReturnUrl("http://pay.egzosn.com");
|
||||
|
||||
@@ -111,4 +111,20 @@ public class QueryOrder {
|
||||
public void setTransactionType(String transactionType) {
|
||||
this.transactionType = transactionType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "QueryOrder{" +
|
||||
"payId=" + payId +
|
||||
", tradeNo='" + tradeNo + '\'' +
|
||||
", outTradeNo='" + outTradeNo + '\'' +
|
||||
", refundAmount=" + refundAmount +
|
||||
", totalAmount=" + totalAmount +
|
||||
", billDate=" + billDate +
|
||||
", billType='" + billType + '\'' +
|
||||
", tradeNoOrBillDate=" + tradeNoOrBillDate +
|
||||
", outTradeNoBillType='" + outTradeNoBillType + '\'' +
|
||||
", transactionType='" + transactionType + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
BIN
pay-java-fuiou/document/~$支付网关商户端开发文档.doc
Normal file
BIN
pay-java-fuiou/document/~$支付网关商户端开发文档.doc
Normal file
Binary file not shown.
@@ -45,7 +45,6 @@ public class UnionPayConfigStorage extends BasePayConfigStorage {
|
||||
* @see #getPid()
|
||||
*/
|
||||
@Deprecated
|
||||
@Override
|
||||
public String getPartner () {
|
||||
return merId;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.math.BigDecimal;
|
||||
import java.net.URLEncoder;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
@@ -153,7 +154,7 @@ public class WxPayService extends BasePayService {
|
||||
|
||||
parameters.put("body", order.getSubject());// 购买支付信息
|
||||
parameters.put("out_trade_no", order.getOutTradeNo());// 订单号
|
||||
parameters.put("spbill_create_ip", "192.168.1.150");
|
||||
parameters.put("spbill_create_ip", StringUtils.isEmpty(order.getSpbillCreateIp()) ? "192.168.1.150" : order.getSpbillCreateIp() );
|
||||
parameters.put("total_fee", order.getPrice().multiply(new BigDecimal(100)).setScale(0, BigDecimal.ROUND_HALF_UP).intValue());// 总金额单位为分
|
||||
|
||||
parameters.put("attach", order.getBody());
|
||||
@@ -224,16 +225,14 @@ public class WxPayService extends BasePayService {
|
||||
|
||||
SortedMap<String, Object> params = new TreeMap<String, Object>();
|
||||
|
||||
|
||||
params.put("partnerid", payConfigStorage.getPid());
|
||||
params.put("package", "prepay_id=" + result.get("prepay_id"));
|
||||
if (WxTransactionType.JSAPI == order.getTransactionType()) {
|
||||
params.put("signType", payConfigStorage.getSignType());
|
||||
params.put("appId", payConfigStorage.getAppid());
|
||||
params.put("prepayid", result.get("prepay_id"));
|
||||
params.put("timeStamp", System.currentTimeMillis() / 1000);
|
||||
params.put("nonceStr", result.get("nonce_str"));
|
||||
} else if (WxTransactionType.APP == order.getTransactionType()) {
|
||||
params.put("partnerid", payConfigStorage.getPid());
|
||||
params.put("appid", payConfigStorage.getAppid());
|
||||
params.put("prepayid", result.get("prepay_id"));
|
||||
params.put("timestamp", System.currentTimeMillis() / 1000);
|
||||
@@ -328,8 +327,8 @@ public class WxPayService extends BasePayService {
|
||||
if (!"SUCCESS".equals(orderInfo.get("return_code"))) {
|
||||
throw new PayErrorException(new WxPayError((String) orderInfo.get("return_code"), (String) orderInfo.get("return_msg")));
|
||||
}
|
||||
if (WxTransactionType.MWEB.equals(orderInfo.get("trade_type"))) {
|
||||
return "<script type=\"text/javascript\">location.href=\"" + orderInfo.get("mweb_url") + ";\"</script>";
|
||||
if (WxTransactionType.MWEB.name().equals(orderInfo.get("trade_type"))) {
|
||||
return String.format("<script type=\"text/javascript\">location.href=\"%s%s\"</script>",orderInfo.get("mweb_url"), StringUtils.isEmpty(payConfigStorage.getReturnUrl()) ? "" : "&redirect_url=" + URLEncoder.encode(payConfigStorage.getReturnUrl()));
|
||||
}
|
||||
throw new UnsupportedOperationException();
|
||||
|
||||
@@ -584,7 +583,7 @@ public class WxPayService extends BasePayService {
|
||||
}
|
||||
|
||||
//获取公共参数
|
||||
Map<String, Object> parameters = new HashMap<>();//getPublicParameters();
|
||||
Map<String, Object> parameters = getPublicParameters();
|
||||
if (StringUtils.isEmpty((String)transactionIdOrBillDate)){
|
||||
parameters.put("out_trade_no", outTradeNoBillType);
|
||||
}else {
|
||||
|
||||
Reference in New Issue
Block a user