ARB----支付


1、前置

1、沙特的的一个支付

2、案列采用java编写

3、网站应该是这个吧, 因为我这边是通过一个PDF文档开发的, https://www.arabbank.com/ar/mainmenu/home

4、介最后贴图验证以及做好后的样子

5、流程: 创建订单 —> 回调判断(支付成功/失败)

6、代码已上传码云,如果起到帮助还请star一下地址:https://gitee.com/xmaxm/payments_hodgepodge

7、开发时使用的文档(因为文档里面可能涉及了一些关键的信息, 就不贴文档上来了): ARB Payment Gateway REST API Integration Doc_V1.11.pdf

8、一些很重要的截图
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2、准备工作

没有, 因为没有登录过, 只有一个PDF

需要说明一点, 金额, 1就是1, 不需要*100

工具类:

package com.tomorrow.payments_hodgepodge.util;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

/**
 * @author Tomorrow
 * @date 2020/11/10 17:27
 */
public class ARBUtil {
    
    
    public static String AES_IV = "PGKEYENCDECIVSPC";

    public static String encryptAES(String key, String encryptString) {
    
    
        byte[] encryptedText = null;
        IvParameterSpec ivspec = null;
        SecretKeySpec skeySpec = null;
        Cipher cipher = null;
        byte[] text = null;
        String s = null;
        try {
    
    
            ivspec = new IvParameterSpec(AES_IV.getBytes("UTF-8"));
            skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
            cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivspec);
            text = encryptString.getBytes("UTF-8");
            encryptedText = cipher.doFinal(text);
            s = byteArrayToHexString(encryptedText);
        } catch (Exception e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            encryptedText = null;
            ivspec = null;
            skeySpec = null;
            cipher = null;
            text = null;
        }
        return s.toUpperCase();
    }


    public static String decryptAES(String key, String encryptedString) {
    
    
        SecretKeySpec skeySpec = null;
        IvParameterSpec ivspec = null;
        Cipher cipher = null;
        byte[] textDecrypted = null;

        try {
    
    
            byte[] b = hexStringToByteArray(encryptedString);
            skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
            ivspec = new IvParameterSpec(AES_IV.getBytes("UTF-8"));
            cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(2, skeySpec, ivspec);
            textDecrypted = cipher.doFinal(b);
        } catch (Exception var10) {
    
    
            var10.printStackTrace();
        } finally {
    
    
            skeySpec = null;
            ivspec = null;
            cipher = null;
        }

        return new String(textDecrypted);
    }

    public static String byteArrayToHexString(byte[] data) {
    
    
        StringBuffer buf = new StringBuffer();

        for (int i = 0; i != data.length; ++i) {
    
    
            int v = data[i] & 255;
            buf.append("0123456789abcdef".charAt(v >> 4));
            buf.append("0123456789abcdef".charAt(v & 15));
        }

        return buf.toString();
    }

    public static byte[] hexStringToByteArray(String s) {
    
    
        int len = s.length();
        byte[] data = new byte[len / 2];

        for (int i = 0; i < len; i += 2) {
    
    
            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i + 1), 16));
        }

        return data;
    }
}

3、ARB 创建订单

public CommonResult createOrder(String orderNo) {
    
    
        JSONObject jsonObject = new JSONObject();
        // 跨门户ID。商家下载相同的商家门户网站
        jsonObject.put("id", tranportalId);
        // 支付网关发送的商家成功URL 通知请求。
        jsonObject.put("responseURL", callback);
        // 支付网关发送的商家错误URL 在处理事务时发生任何错误时响应。
        jsonObject.put("errorURL", callback);

        JSONObject requestParams = new JSONObject();
        // 交易金额
        requestParams.put("amt", "12.00");
        // 定义事务操作 采购:1 退款:2 无效:3 调查:8
        requestParams.put("action", "1");
        // Tranportal密码。在商家门户下载相同的商家。
        requestParams.put("password", password);
        // 跨门户ID。商家下载相同的商家门户网站
        requestParams.put("id", tranportalId);
        // KSA的3位货币代码例:682
        requestParams.put("currencyCode", "682");
        // 商户唯一参考编号
        requestParams.put("trackId", orderNo);
        // 用户(商家)定义这些字段。现场数据为 与事务请求一起传递,然后返回 在事务响应中。商户应确保 字段在不需要传递数据时留空。
        requestParams.put("udf1", "udf1text");
//        requestParams.put("udf2", "udf2text");
//        requestParams.put("udf3", "udf3text");
//        requestParams.put("udf4", "udf4text");
//        requestParams.put("udf5", "udf5text");
        // 支付网关发送的商家成功URL 通知请求。
        requestParams.put("responseURL", callback);
        // 支付网关发送的商家错误URL 在处理事务时发生任何错误时响应。
        requestParams.put("errorURL", callback);

//        JSONObject accountDetailsParams = new JSONObject();
//        // 8位银行识别码
//        accountDetailsParams.put("bankIdCode", "1****");
//        // 24位伊班数字
//        accountDetailsParams.put("iBanNum", "5678****76254");
//        // 服务数量, 服务金额
//        accountDetailsParams.put("serviceAmount", "200.00");
//        // 日期格式:YYYYDDMM
//        accountDetailsParams.put("valueDate", "20203112");
//
//        List<JSONObject> list = new ArrayList<>();
//        list.add(accountDetailsParams);
//        // 条件如果商人选择未来支付。 分开付款细节。
//        requestParams.put("accountDetails", list);

        List<JSONObject> requestEncryptAES = new ArrayList<>();
        requestEncryptAES.add(requestParams);
        String encryptAES = ARBUtil.encryptAES(key, JSONObject.toJSONString(requestEncryptAES));

        jsonObject.put("trandata", encryptAES);

        // 请求数据
        List<JSONObject> requestBody = new ArrayList<>();
        requestBody.add(jsonObject);

        Map<String, String> map = new HashMap<>();
        map.put("content-type", "application/json");

        try {
    
    
            String responseParams = HttpsUtils.HttpsRequest(BANK_HOSTED_URL, "POST", JSONObject.toJSONString(requestBody), map);
            JSONArray jsonArray = JSONObject.parseArray(responseParams);
            JSONObject object = (JSONObject) jsonArray.get(0);
            String status = object.getString("status");
            if ("1".equals(status)) {
    
    
                String result = object.getString("result");
                String[] split = result.split(":");
                String requestUrl = split[1] + ":" + split[2] + "?PaymentID=" + split[0];
                return CommonResult.success("SUCCESS", requestUrl);
            }
            return CommonResult.failMessage(500, "FAIL", object);
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
        return CommonResult.fail(500, "FAIL");
    }

在这里插入图片描述
在这里插入图片描述

4、ARB 回调

public CommonResult callback(HttpServletRequest request) {
    
    
//        //获取所有参数的map集合
//        Map<String, String[]> parameterMap = request.getParameterMap();
//        //遍历
//        Set<String> keySet = parameterMap.keySet();
//        for (String name : keySet) {
    
    
//            //根据键获取值
//            String[] values = parameterMap.get(name);
//            System.out.println(name);
//            for (String value : values) {
    
    
//                System.out.println(value);
//            }
//            System.out.println("------------");
//        }
        String paymentid = request.getParameter("paymentid");
        String trackid = request.getParameter("trackid");
        String custid = request.getParameter("custid");
        String trandata = request.getParameter("trandata");
        // 参数解密
        String decryptAES = ARBUtil.decryptAES(key, trandata);
        try {
    
    
            decryptAES = URLDecoder.decode(decryptAES, "UTF-8");
            log.info("解密后的数据: {}", decryptAES);
            JSONArray jsonArray = JSONObject.parseArray(decryptAES);
            JSONObject jsonObject = (JSONObject) jsonArray.get(0);
            if ("CAPTURED".equals(jsonObject.getString("result"))) {
    
    
                // transId 退款ID
                return CommonResult.success("SUCCESS", jsonObject.getString("transId"));
            }
            if (jsonObject.getString("result") != null) {
    
    
                return CommonResult.failMessage(500, "FAIL", jsonObject.getString("result"));
            } else {
    
    
                return CommonResult.failMessage(500, "FAIL", jsonObject.getString("errorText"));
            }
        } catch (UnsupportedEncodingException e) {
    
    
            e.printStackTrace();
        }
        return CommonResult.fail(500, "FAIL");
    }

在这里插入图片描述

5:退款

退款接口是上面截图的 Merchant Hosted对应的请求地址

@Override
    public CommonResult arbRefund(String amount, String refundOrderNo) {
    
    
        JSONObject jsonObject = new JSONObject();
        // 跨门户ID。商家下载相同的商家门户网站
        jsonObject.put("id", tranportalId);


        JSONObject requestParams = new JSONObject();
        // 跨门户ID。商家下载相同的商家门户网站
        requestParams.put("id", tranportalId);
        // Tranportal密码。在商家门户下载相同的商家。
        requestParams.put("password", password);
        // 定义事务操作 采购:1 退款:2 无效:3 调查:8
        requestParams.put("action", "2");
        // 交易金额
        requestParams.put("amt", amount);
        // KSA的3位货币代码例:682
        requestParams.put("currencyCode", "682");
        // 退款transId支付成功后返回的数据
        requestParams.put("transId", refundOrderNo);

        List<JSONObject> requestEncryptAES = new ArrayList<>();
        requestEncryptAES.add(requestParams);
        String encryptAES = ARBUtil.encryptAES(key, JSONObject.toJSONString(requestEncryptAES));

        jsonObject.put("trandata", encryptAES);

        // 请求数据
        List<JSONObject> requestBody = new ArrayList<>();
        requestBody.add(jsonObject);

        Map<String, String> map = new HashMap<>();
        map.put("content-type", "application/json");

        try {
    
    
            String responseParams = HttpsUtils.HttpsRequest(MERCHANT_HOSTED_URL, "POST", JSONObject.toJSONString(requestBody), map);
            JSONArray jsonArray = JSONObject.parseArray(responseParams);
            JSONObject object = (JSONObject) jsonArray.get(0);
            String status = object.getString("status");
            if ("1".equals(status)) {
    
    
                // 参数解密
                String decryptAES = ARBUtil.decryptAES(key, object.getString("trandata"));
                decryptAES = URLDecoder.decode(decryptAES, "UTF-8");
                log.info("解密后的数据: {}", decryptAES);
                return CommonResult.success("SUCCESS", object);
            }
            return CommonResult.failMessage(500, "FAIL", object);
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
        return CommonResult.fail(500, "FAIL");
    }

6:杂谈

1、代码上传码云地址:https://gitee.com/xmaxm/payments_hodgepodge

2、创建订单成功后, 会返回一个连接,
  ①请求这个链接进行支付
  ②ARB会请求我们的回调地址
  ③回调接口返回数据
  ④ARB响应第一步

3、测试卡:
在这里插入图片描述

4、文档截图如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述




提供一个群:807770565,欢迎各位进来尬聊 (人不多, 进了就不要退了, 要不就不进, 跪求留一点人, 人多了就活跃了, 跪谢)
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_38637558/article/details/109749851
今日推荐