123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- package com.ywt.alipaympapi.service;
- import com.alibaba.fastjson.JSON;
- import com.alibaba.fastjson.JSONArray;
- import com.alibaba.fastjson.JSONObject;
- import com.alipay.api.AlipayApiException;
- import com.alipay.api.domain.CommerceAppUploadRequestContent;
- import com.alipay.api.request.AlipayCommerceAppAuthUploadRequest;
- import com.alipay.api.response.AlipayCommerceAppAuthUploadResponse;
- import com.alipay.easysdk.base.oauth.models.AlipaySystemOauthTokenResponse;
- import com.alipay.easysdk.factory.Factory;
- import com.ywt.alipaympapi.core.utils.CheckUtil;
- import com.ywt.alipaympapi.core.utils.DateUtil;
- import com.ywt.alipaympapi.face.impl.AlipayService;
- import com.ywt.alipaympapi.models.Constants;
- import com.ywt.core.exception.AppMessageException;
- import lombok.extern.slf4j.Slf4j;
- import org.apache.tomcat.util.bcel.Const;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Service;
- import redis.clients.jedis.JedisCommands;
- import java.io.UnsupportedEncodingException;
- import java.net.URLEncoder;
- import java.util.Date;
- /**
- * 支付宝“智能”消息服务
- * 参考文档 <a href="https://opendocs.alipay.com/pre-open/01odaz">医疗小程序智能消息推送接入方案</a>
- *
- * @author Walker
- * Created on 2022/9/28
- */
- @Slf4j
- @Service
- public class MessageService {
- @Autowired
- AlipayService alipayService;
- @Autowired
- JedisCommands jedisCommands;
- /**
- * 小程序用 authCode 换取 accessToken
- */
- public String getAccessToken(String authCode) {
- String accessToken = "";
- try {
- AlipaySystemOauthTokenResponse response = Factory.Base.OAuth().getToken(authCode);
- log.info("MessageService#getAccessToken(authCode={} ):\n {}", authCode, JSON.toJSONString(response));
- accessToken = response.getAccessToken();
- } catch (Exception e) {
- log.error("MessageService#getAccessToken(authCode={} ):\n {}", authCode, e.getMessage(), e);
- }
- return accessToken;
- }
- /**
- * 发送“智能”消息
- *
- * @param appId 小程序 appId
- * @param alipayUid 支付宝用户 id
- * @param jsonBody 业务参数,具体根据业务类型按照文档拼接
- */
- public void sendIntelliMsg(String appId, String alipayUid, JSONObject jsonBody, String hospitalPid, String tenantAppId) {
- try {
- String rk = String.format(Constants.RK_ACCESS_TOKEN, appId, alipayUid);
- String accessToken = jedisCommands.get(rk);
- CheckUtil.ensureNotEmpty(accessToken, rk + " 无法获取 accessToken");
- AlipayCommerceAppAuthUploadRequest request = new AlipayCommerceAppAuthUploadRequest();
- request.setServiceName("alipay.commerce.app.data");//应用服务名称 固定值 String(256) 不可空
- request.setTargetId(hospitalPid); //目标用户 String(64) 签约商家 PID 不可空
- CommerceAppUploadRequestContent content = new CommerceAppUploadRequestContent(); //服务数据参数
- content.setTenantAppId(tenantAppId); //租户应 用ID String(64) 支付宝分配 不可空
- content.setActivityId("upload_hospital_order"); //业务流程ID String(64) 不可空 此处固定为“upload_hospital_order”
- content.setBody(JSONObject.toJSONString(jsonBody));
- request.setContent(content);
- log.info("MessageService#sendIntelliMsg(appId={}, accessToken={} ): 入参:{}", appId, accessToken, JSON.toJSONString(request));
- AlipayCommerceAppAuthUploadResponse response = alipayService.getAlipayClient(appId).execute(request, accessToken);
- log.info("MessageService#sendIntelliMsg(appId={}, accessToken={} ): 响应:{}", appId, accessToken, JSON.toJSONString(response));
- } catch (AppMessageException e) {
- log.error("MessageService#sendIntelliMsg(): 业务异常:{}", e.getMessage());
- } catch (Exception e) {
- log.error("MessageService#sendIntelliMsg(appId={} , jsonBody={} , alipayUid={} ):\n {}", appId, jsonBody, alipayUid, e.getMessage(), e);
- }
- }
- /**
- * 发送预约挂号单消息
- */
- public void sendRegMsg(int orderId, String orderNo, String alipayUid, String orderCreateTime, String orderAmountStr,
- String tradeNo, String hospitalName, String deptName, String doctorName, String doctorId,
- String patientName, String regDate, String deptLoc, String appId, String merchantOrderStatus,
- String isvPid, String hospitalPid, String tenantAppId, String hospitalRegId) throws AppMessageException {
- CheckUtil.ensureNotEmpty(deptLoc, "科室位置不能为空");
- // 小程序跳转路径
- String pathParam = "";
- try {
- pathParam = URLEncoder.encode(String.format("?header=show&orderId=%d&pageType=appointment-result&title=挂号详情", orderId), "utf-8");
- } catch (UnsupportedEncodingException e) {
- log.error("MessageService#sendRegMsg UnsupportedEncodingException: {}", e.getMessage(), e);
- }
- String mpPath = String.format("alipays://platformapi/startapp?appId=%s&page=antbuilder/industry/hospitalV2/pages/page-no-pull/index%s", appId, pathParam);
- JSONObject jsonBody = new JSONObject(); //业务流程参数 String(6000) 业务流程请求参数说明
- jsonBody.put("out_biz_no", orderNo);//医院预约单订单号 唯一不重复(同一 家 ISV 接入的所有 医院的挂号单、检 查号、医药单都不 可重复) String(128)
- jsonBody.put("partner_id", isvPid); //ISV的PID,支付宝id(2088 开头)。同一家ISV 请保持一致!
- jsonBody.put("buyer_id", alipayUid);//就诊人 id,授权 人id 就诊人在支付宝平 台的 2088 开头 16 位id
- jsonBody.put("tiny_app_id", appId);//医院在支付宝的小 程序id
- jsonBody.put("order_create_time", orderCreateTime);//订单创建时间
- jsonBody.put("order_modified_time", DateUtil.formatDate(new Date(), ""));//订单修改时间
- jsonBody.put("amount", orderAmountStr);//订单金额
- jsonBody.put("pay_amount", orderAmountStr);//支付金额
- jsonBody.put("trade_no", tradeNo);//支付宝交易号
- jsonBody.put("order_type", "HOSPITAL_ORDER"); // 固定为 HOSPITAL_ORDER
- jsonBody.put("out_biz_type", "HOSPITAL_APPOINTMENT"); // 固定值 HOSPITAL_APPOINTMENT
- // 状态文档:https://gw.alipayobjects.com/os/bmw-prod/05064ae2-e3c7-4e6c-93ed-ad4740b66000.pdf
- // MERCHANT PREORDER SUCCESS 预约成功
- // MERCHANT NUM TAKEN 己取号
- // MERCHANT WAIT CHECK IN 待签到
- // MERCHANT CALL NUM 叫号中
- // MERCHANT NUM ARRIVED 己到号
- // MERCHANT NUM PASSED 已过号
- // MERCHANT FINISHED 已完成
- // MERCHANT CLOSED 已取消
- // MERCHANT REFUNDED 已退款
- jsonBody.put("merchant_order_status", merchantOrderStatus); //状态 String(64) 枚举详见文档
- JSONArray itemOrderList = new JSONArray();
- JSONObject itemOrder = new JSONObject();
- itemOrder.put("item_name", "预约挂号");//商品名称
- itemOrder.put("quantity", "1");//商品数量
- itemOrder.put("sku_id", "1"); //商品 skuId
- itemOrder.put("unit_price", orderAmountStr);//商品单价
- itemOrderList.add(itemOrder);
- jsonBody.put("item_order_list", itemOrderList);
- JSONObject extInfo = new JSONObject();
- extInfo.put("hospital", hospitalName);//医院名称
- extInfo.put("hospital_register_id", hospitalRegId);//医院登记号
- extInfo.put("department", deptName);//就诊科室
- extInfo.put("dept_num", "");//诊室编号
- extInfo.put("dept_loc", deptLoc);//科室位置
- extInfo.put("navigation", "");//导航地址
- extInfo.put("doctor", doctorName);//医生名称
- extInfo.put("doctor_rank", "");//医生职级
- extInfo.put("doctor_id", doctorId);//医生 id
- extInfo.put("doctor_avatar", "");//医生头像 url
- extInfo.put("patient", patientName);//就诊人 必须与 buy_id 对 应的姓名一致
- extInfo.put("scheduled_time", regDate);//预约时间
- extInfo.put("take_num_url", "");//取号入口
- extInfo.put("take_num_password", "");//取号密码
- extInfo.put("call_num_url", "");//叫号进度入口
- extInfo.put("medical_order_id", "");//就诊单id
- extInfo.put("medical_num", "");//就诊/检 查序号
- extInfo.put("merchant_order_link_page", mpPath);//订单链接
- jsonBody.put("ext_info", extInfo);
- sendIntelliMsg(appId, alipayUid, jsonBody, hospitalPid, tenantAppId);
- }
- }
|