JAVA分布式医疗云平台系统开发实战第一节 open-his系统介绍

Open-his 支付系统                                                                        

1.目的                                                                                                              

就是为用户提供一些支付的手段,提供类似银联支付,微信支付,支付宝支付等等的手段! 

2.说明                                                                                                              

我们在众多的支付系统里面,应该优先选择微信支付(因为我们现在微信的小程序,但是微信支付必须  是企业用户,而且你的小程序已经上线 2 周左右,你才能使用微信支付)  所以我们这里面只能选择支付宝支付了  因为支付宝宝的支付流程和微信支持的流程非常相似,我们会一个,别的道理差不多
3.申请支付宝的账号                                                                                         

支付宝开放平台

3.1扫码登录

 3.2账号申请

3.3下载支付宝测试版  

安装好的效果

3.4登录测试版支付宝

 

 3.5登录成功后

 

3.6充值

 

4.生成公钥和私钥 

 

 

 

5.集成支付宝扫码支付功能                                                                               

5.1创建项目 alipay-demo                                                              

下载demo

5.2导入依赖包 

 

5.2.1修改pom文件 

<!--引入支付宝相关的jar包--> 
<dependency> 
    <groupId>com.alibaba</groupId> 
    <artifactId>alipay-sdk-java</artifactId> 
    <version>3.3.0</version> 
    <scope>system</scope> 
    <systemPath>${project.basedir}/lib/alipay-sdk-java-3.3.0.jar</systemPath> </dependency> 
<dependency> 
    <groupId>com.alibaba</groupId> 
    <artifactId>alipay-trade-sdk-java</artifactId> 
    <version>1.0</version> 
    <scope>system</scope>   
    <systemPath>${project.basedir}/lib/alipay-trade-sdk-1.0.jar</systemPath> </dependency> 

5.3.创建zfbinfo.properties

 

5.5创建payService 

import com.alipay.api.response.AlipayTradePrecreateResponse; 
import com.alipay.demo.trade.config.Configs; 
import com.alipay.demo.trade.model.builder.AlipayTradePrecreateRequestBuilder; import com.alipay.demo.trade.model.builder.AlipayTradeRefundRequestBuilder; import com.alipay.demo.trade.model.result.AlipayF2FPrecreateResult; 
import com.alipay.demo.trade.model.result.AlipayF2FRefundResult; 
import com.alipay.demo.trade.service.AlipayTradeService; 
import com.alipay.demo.trade.service.impl.AlipayTradeServiceImpl; 
import org.apache.commons.logging.Log; 
import org.apache.commons.logging.LogFactory; 

import java.util.HashMap; import java.util.Map; 

/** 
 * @Author: 
 * 支付类 
 */ 
public class PayService {   

    //输出日志 
    static Log log = LogFactory.getLog("trade_precreate");     //支付定当关付的对象 
    static AlipayTradeService tradeService; 

    //初始化对象 
    static { 
        // 一定要在创建AlipayTradeService之前设置参数 
        Configs.init("zfbinfo.properties"); 
        tradeService = new AlipayTradeServiceImpl.ClientBuilder().build();     } 

    // 商户操作员编号,添加此参数可以为商户操作员做销售统计     static String operatorId = "test_operator_id"; 

    // (必填) 商户门店编号,通过门店号和商家后台可以配置精准到门店的折扣信息,详询支付宝技术支 持 
    static String storeId = "test_store_id"; 

    // 支付超时,定义为120分钟 
    static String timeoutExpress = "120m"; 


    /** 
     * 支付的方法 
     * @param outTradeNo  (必填) 商户网站订单系统中唯一订单号,64个字符以内,只能包含字母、 数字、下划线, 需保证商户系统端不能重复,建议通过数据库sequence生成, 
     * @param subject (必填) 订单标题,粗略描述用户的支付目的。如“喜士多(浦东店)消费” 
     * @param totalAmount (必填) 订单总金额,单位为元,不能超过1亿元 
     * @param undiscountableAmount (可选) 订单不可打折金额,可以配合商家平台配置折扣活 动,如果酒水不参与打折,则将对应金额填写至此字段 
     * @param body 订单描述,可以对交易或商品进行一个详细地描述,比如填写"购买商品2件共15.00 元" 
     * @param notifyUrl /支付宝服务器主动通知商户服务器里指定的页面http路径,根据需要设置 
     * @return 
     */ 
    public static Map<String,Object> pay(String outTradeNo, 
                                        String subject, 
                                         String totalAmount, 
                                         String undiscountableAmount, 
                                         String body, 
                                         String notifyUrl 
                                        ){ 
        System.out.println(notifyUrl); 
        AlipayTradePrecreateRequestBuilder builder =new  AlipayTradePrecreateRequestBuilder() 
                .setSubject(subject) 
                .setTotalAmount(totalAmount) 
                .setOutTradeNo(outTradeNo) 
                .setUndiscountableAmount(undiscountableAmount) 
                .setBody(body) 
                .setOperatorId(operatorId) 
                .setStoreId(storeId) 
                .setTimeoutExpress(timeoutExpress) 
                .setNotifyUrl(notifyUrl); 
//              .setNotifyUrl("http://www.test-notify-url.com");//支付宝服务器主动通 知商户服务器里指定的页面http路径,根据需要设置 
        //发起支付 
 

8   
        AlipayF2FPrecreateResult result = tradeService.tradePrecreate(builder);         Map<String,Object> map=new HashMap<>(); 
        String msg; 
        Integer code; 
        switch (result.getTradeStatus()) { 
            case SUCCESS: 
                log.info("支付宝预下单成功: )"); 
                AlipayTradePrecreateResponse res = result.getResponse(); 
                //得到支付码,本质就是一个URL 
                String qrCode=res.getQrCode(); 
                map.put("qrCode",qrCode); 
                msg="下单成功"; 
                code=200; 
                break; 
            case FAILED: 
                log.error("支付宝预下单失败!!!"); 
                msg="下单失败"; 
                code=500; 
                break; 

            case UNKNOWN: 
                log.error("系统异常,预下单状态未知!!!"); 
                msg="系统异常"; 
                code=404; 
                break; 
            default: 
                log.error("不支持的交易状态,交易返回异常!!!");                 msg="不支持的交易状态"; 
                code=404; 
                break; 
        } 
        map.put("msg",msg); 
        map.put("code",code); 
        return map; 
    } 
} 

5.6测试支付

import java.util.Map; 

/** 
 * @Author: 
 */ 
public class TestPay { 
    public static void main(String[] args) { 
        String outTradeNo="OD123124124ABCDE94"; 
        String subject="SXT-医疗管理系统支付平台"; 
        String totalAmount="100"; 
        String undiscountableAmount=null; 
        String body="买药用的"; 
        String notifyUrl="http://45314rh250.qicp.vip/pay/callback/"+outTradeNo;         Map<String, Object> pay = PayService.pay(outTradeNo, subject,  totalAmount, undiscountableAmount, body, notifyUrl); 
        System.out.println(pay); 
    } 
}   
10 
http://45314rh250.qicp.vip/pay/callback/OD123124124ABCDE94 
16:21:48.372 [main] INFO  
com.alipay.demo.trade.service.impl.AlipayTradeServiceImpl - trade.precreate  bizContent: 
{"out_trade_no":"OD123124124ABCDE94","total_amount":"100","subject":"SXT-医疗管理 系统支付平台","body":"买药用 
的","operator_id":"test_operator_id","store_id":"test_store_id","timeout_express" :"120m"} 
16:21:48.925 [main] DEBUG sdk.biz.err - 2030-02-13  
16:21:48^_^https://openapi.alipaydev.com/gateway.do?alipay_sdk=alipay-sdk-java- 3.3.0&app_id=2021000118647783&biz_content=%7B%22out_trade_no%22%3A%22OD123124124 ABCDE94%22%2C%22total_amount%22%3A%22100%22%2C%22subject%22%3A%22SXT- %E5%8C%BB%E7%96%97%E7%AE%A1%E7%90%86%E7%B3%BB%E7%BB%9F%E6%94%AF%E4%BB%98%E5%B9%B 3%E5%8F%B0%22%2C%22body%22%3A%22%E4%B9%B0%E8%8D%AF%E7%94%A8%E7%9A%84%22%2C%22ope rator_id%22%3A%22test_operator_id%22%2C%22store_id%22%3A%22test_store_id%22%2C%2 2timeout_express%22%3A%22120m%22%7D&charset=utf- 8&format=json&method=alipay.trade.precreate&notify_url=http%3A%2F%2F45314rh250.q icp.vip%2Fpay%2Fcallback%2FOD123124124ABCDE94&sign=PGusujk2v%2F3Qy4dPwTJldcjJ8AE 30VWpHlvFdEPPHsrWlkWD65f7fkAe8cxdxGYUShwatdEIe9NUhJixAUfZ4G3h30fpn8nAjtxCSRSG%2B 51C3MLQDM%2FMeCf1Gb3P6%2Fr11VFBu8vYTs1kjaTl1XAiFCCSRdseD1A3AzUdSvLcJxMPGAzYxICfq EVQjnqswqGN5%2FQaOjvSm3GTCSBbAt9rxA9t6%2Bq4JABZjFX4lurHeocnSBTRAbRQb%2FtD%2FpErZ AR2eUm%2B8FEeLg2l0U6kBNZjvPZmeYs%2FyIXllCoeq3bhhNjPTrANBZoG3ERDOomRMVC95ZsCrpBmB PJrOr4VnbmAtQ%3D%3D&sign_type=RSA2&timestamp=2022-02-13+16%3A21%3A48&version=1.0 16:21:50.223 [main] INFO sdk.biz.err -  
Summary^_^10000^_^null^_^ProtocalMustParams:charset=utf- 
8&method=alipay.trade.precreate&sign=PGusujk2v/3Qy4dPwTJldcjJ8AE30VWpHlvFdEPPHsr WlkWD65f7fkAe8cxdxGYUShwatdEIe9NUhJixAUfZ4G3h30fpn8nAjtxCSRSG+51C3MLQDM/MeCf1Gb3 P6/r11VFBu8vYTs1kjaTl1XAiFCCSRdseD1A3AzUdSvLcJxMPGAzYxICfqEVQjnqswqGN5/QaOjvSm3G TCSBbAt9rxA9t6+q4JABZjFX4lurHeocnSBTRAbRQb/tD/pErZAR2eUm+8FEeLg2l0U6kBNZjvPZmeYs 
/yIXllCoeq3bhhNjPTrANBZoG3ERDOomRMVC95ZsCrpBmBPJrOr4VnbmAtQ==&notify_url=http:// 45314rh250.qicp.vip/pay/callback/OD123124124ABCDE94&version=1.0&app_id=202100011 8647783&sign_type=RSA2&timestamp=2022-02-13  16:21:48^_^ProtocalOptParams:alipay_sdk=alipay-sdk-java- 3.3.0&format=json^_^ApplicationParams:biz_content= {"out_trade_no":"OD123124124ABCDE94","total_amount":"100","subject":"SXT-医疗管理 系统支付平台","body":"买药用 
的","operator_id":"test_operator_id","store_id":"test_store_id","timeout_express" :"120m"}^_^553ms,1282ms,16ms 
16:21:50.223 [main] INFO  
com.alipay.demo.trade.service.impl.AlipayTradeServiceImpl -  
{"alipay_trade_precreate_response": 
{"code":"10000","msg":"Success","out_trade_no":"OD123124124ABCDE94","qr_code":"h ttps:\/\/qr.alipay.com\/bax04481md03pfwbl1ay00ad"},"sign":"bRlOc5cL2psx0MeNwLVwB kMwTlvQA79UjNNV76yim3ImkxM643DiXU5Q0D04wfYoNVUvELWpJ9NqNo0bztr0gT1t8nafOkqnOwSN0 525DjT8gWwEldyyqsCjlCTpgDh66LGK3/4JbuYXysb5bhKQHzAVB5Ux8TxK2sbo1tpSYjCRlBc5x6GzS FQ2f8H+cPQgjcikDOILS5ZGUG6dZZ3gGHraswLmlpAftkl8j6yB4i/o/lnhBTUnOerAnTubSTutH+ARp 0iiEMyG4EjVfp0bQso7Ll+EY+bbvqSXIXmL5Q5cRWKPZO21oGxPSSL+M16AFVShgvulFkU5sMyFB7/fa A=="} 
16:21:50.223 [main] INFO trade_precreate - 支付宝预下单成功: ) 
{msg=下单成功, code=200, qrCode=https://qr.alipay.com/bax04481md03pfwbl1ay00ad} 

5.7创建PayController回调方法

下载花生壳,配置回调地址

 

 

5.7.1编写controller

import com.alibaba.fastjson.JSON; 
import com.alipay.api.AlipayApiException; 
import com.alipay.api.internal.util.AlipaySignature; 
import com.bjsxt.pay.AlipayConfig; 
import org.apache.commons.lang3.StringUtils; 
import org.apache.commons.logging.Log; 
import org.apache.commons.logging.LogFactory; 
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; 

import javax.servlet.http.HttpServletRequest; import java.util.Enumeration; 
import java.util.HashMap; 
import java.util.Map; 

/** 
 * @Author: 
 */ 
@RestController @RequestMapping("pay") 
public class PayController { 

    //输出日志 
    static Log log = LogFactory.getLog("PayController"); 

    @PostMapping("callback/{orderId}") 
    public void callback(@PathVariable String orderId, HttpServletRequest  request) { 
        Map<String, String> parameterMap = this.getParameterMap(request); 
        String trade_status = parameterMap.get("trade_status"); 
        if ("TRADE_SUCCESS".equals(trade_status)) { 
            try {   

                //验证是否为支付宝发来的信息 
                boolean singVerified = AlipaySignature.rsaCheckV1(parameterMap,  AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type); 
                System.out.println(singVerified);//只有支付宝调用我们系统的接口才能去更 新系统订单状态 
                log.info("验证签名结果{}:" + singVerified); 
                String refund_fee = parameterMap.get("refund_fee"); 
                if (StringUtils.isNotBlank(refund_fee)) { 
                    //说明是退费 
                    System.out.println("退费成功:退费的子订单ID为:" +  
parameterMap.get("out_biz_no")); 
                    //更新订单状态 
                } else { 
                    //说明支付 
                    System.out.println("收费成功,平台ID" +  
parameterMap.get("trade_no")); 
                } 
                System.out.println(JSON.toJSON(parameterMap)); 
            } catch (AlipayApiException e) { 
                e.printStackTrace(); 
                log.error(orderId + "验证签名出现异常"); 
            } 
        }else if("WAIT_BUYER_PAY".equals(trade_status)){ 
            System.out.println("二维码已扫描,等待支付"); 
        } 
    } 

    /** 
     * 获取request中的参数集合转Map 
     * Map<String,String> parameterMap = RequestUtil.getParameterMap(request)      * 
     * @param request 
     * @return 
     */ 
    public Map<String, String> getParameterMap(HttpServletRequest request) { 
        Map<String, String> map = new HashMap<>(); 
        Enumeration<String> paramNames = request.getParameterNames(); 
        while (paramNames.hasMoreElements()) { 
            String paramName = paramNames.nextElement(); 
            String[] paramValues = request.getParameterValues(paramName); 
            if (paramValues.length == 1) { 
                String paramValue = paramValues[0]; 
                if (paramValue.length() != 0) { 
                    map.put(paramName, paramValue); 
                } 
            } 
        } 
        return map; 
    } 
} 
 

13  

 5.7.2测试结果

当用户扫码之后会回调一次,支付成功之后会回调一次

5.8测试退费

修改PayService

/** 
     * 退费 
     * @param outTradeNo  外部应该交易ID 
     * @param tradeNo  平台在支付成之后返回的平台【属于支付宝平台的ID】 
     * @param refundAmount  退款金额 
     * @param refundReason 退款原因 
     * @param outRequestNo  是否支持部分退款 
     */ 
    public static Map<String,Object>  payBack(String outTradeNo,String  
tradeNo,String refundAmount,String refundReason,String outRequestNo){ 
        AlipayTradeRefundRequestBuilder builder = new  AlipayTradeRefundRequestBuilder() 
                .setOutTradeNo(outTradeNo)//outTradeNo  tradeNo只需要有一个就行 
                .setTradeNo(tradeNo) 
                .setRefundAmount(refundAmount) 
                .setRefundReason(refundReason) 
                .setOutRequestNo(outRequestNo) 
//                .setNotifyUrl(notifyUrl)//没有用 因为这个回调地址就是收费时的回调地址                 .setStoreId(storeId); 
        //退费请求 
        AlipayF2FRefundResult result = tradeService.tradeRefund(builder); 
        Map<String,Object> map=new HashMap<>(); 
        Integer code=null; 
        String msg=""; 
        switch (result.getTradeStatus()) { 
            case SUCCESS: 
                log.info("支付宝退款成功: )"); 
                code=200; 
                msg=result.getResponse().getSubMsg(); 
                break; 

            case FAILED: 
                log.error("支付宝退款失败!!!"); 
                code=500; 
                msg=result.getResponse().getSubMsg();                 break; 

            case UNKNOWN: 
                log.error("系统异常,订单退款状态未知!!!");                 code=500; 
                msg=result.getResponse().getSubMsg(); 
                break; 

            default: 
                log.error("不支持的交易状态,交易返回异常!!!");                 code=500; 
                msg=result.getResponse().getSubMsg(); 
                break; 
        } 
        map.put("code",code); 
        map.put("msg",msg); 
        return map; 
    } 

创建测试类TestRefund

/** 
 * @Author: 
 * 测试退费 
 */ 
public class TestRefund { 
    public static void main(String[] args) { 
        String outTradeNo="OD123124124ABCDEF5"; 
        String tradeNo="2021110922001471560501815457"; 
        String subject="SXT-医疗管理系统支付平台"; 
        String refudAmount="60"; 
        String refudReason="不想要了"; 
        Map<String, Object> map = PayService.payBack(outTradeNo, tradeNo,  refudAmount, refudReason, "BK12345681"); 
        System.out.println(map); 
    } 
} 
 

15  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

办公模板库 素材蛙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值