当前位置: 首页 > article >正文

华为支付-商户基础支付场景开发步骤

一、预下单(服务器开发)
开发者按照商户模型调用直连商户预下单或平台类商户/服务商预下单接口获取预支付ID(prepayId)。
为保证支付订单的安全性和可靠性需要对请求body和请求头PayMercAuth对象内的入参排序拼接进行签名。请参考排序拼接和签名示例代码。

构建订单信息参数orderStr。
商户服务器需要将客户端支付接口入参orderStr签名后返回给客户端。

说明:orderStr中sign字段签名规则是将除sign外的参数都做排序拼接后再签名,签名值赋值给sign字段。

以下为开放API接口请求及orderStr构建示例代码片段:

import com.huawei.petalpay.paymentservice.apiservice.client.model.PreOrderCreateRequestV2;
import com.huawei.petalpay.paymentservice.apiservice.client.model.PreOrderCreateResponse;
import com.huawei.petalpay.paymentservice.apiservice.client.model.PreSignRequestV2;
import com.huawei.petalpay.paymentservice.apiservice.client.model.PreSignResponse;
import com.huawei.petalpay.paymentservice.core.client.DefaultPetalPayClient;
import com.huawei.petalpay.paymentservice.core.client.PetalPayClient;
import com.huawei.petalpay.paymentservice.example.common.CommonResponse;
import com.huawei.petalpay.paymentservice.example.common.MercConfigUtil;
import lombok.extern.slf4j.Slf4j;

public class MercApiController {
    private static PetalPayClient payClient = new DefaultPetalPayClient(MercConfigUtil.getMercConfig());
    /**
     * 预下单接口调用
     */
    public CommonResponse aggrPreOrderForAppV2() {
        // 组装对象
        PreOrderCreateRequestV2 preOrderReq = getPreOrderCreateRequestV2();
        PreOrderCreateResponse response = null;
        try {
            response = payClient.execute("POST", "/api/v2/aggr/preorder/create/app", PreOrderCreateResponse.class,
                preOrderReq);
        } catch (Exception e) {
            // todo 异常处理
            log.error("request error ", e);
            return CommonResponse.buildErrorRsp(e.getMessage());
        }
        if (!validResponse(response)) {
            // todo 异常处理
            log.error("response is invalid ", response);
            return CommonResponse.buildFailRsp(response);
        }
        return CommonResponse.buildSuccessRsp(payClient.buildOrderStr(response.getPrepayId()));
    }
    public static boolean validResponse(BaseGwRspWithSign rsp) {
        return rsp != null && "000000".equals(rsp.getResultCode());
    }
    /**
     * 预下单接口请求参数组装,商户请根据业务自行实现
     */
    public static PreOrderCreateRequestV2 getPreOrderCreateRequestV2() {
        return PreOrderCreateRequestV2.builder()
            .mercOrderNo("pay-example-" + System.currentTimeMillis()) // 每次订单号都要变,请将pay-example-修改为商户自己的订单前缀
            .appId(MercConfigUtil.APP_ID)  // appId,需要配置为与商户绑定的正确的appId
            .mercNo(MercConfigUtil.MERC_NO) // 商户的商户号
            .tradeSummary("请修改为对应的商品简称") // 请修改为商品简称
            .bizType("100002") // (100001:虚拟商品购买,100002:实物商品购买,100004:航旅交通服务,100005:活动票务订购,100006:商业服务消费,100007:生活服务消费,100008:租金缴纳,100009:会员费缴纳,100011:其他商家消费,100037:公共便民服务)
            .totalAmount(2L)
            .callbackUrl("https://www.xxxxxx.com/hw/pay/callback") // 回调通知地址,通知URL必须为直接可访问的URL,要求为https地址。最大长度为512。请替换为格式正确的结果通知回调地址。
            .build();
    }

    二、拉起华为支付收银台(端侧开发)
    商户客户端使用orderStr作为参数调用requestPayment接口拉起Payment Kit支付收银台。
    当接口通过.then()方法返回时,则表示当前订单支付成功,通过.catch()方法返回表示订单支付失败。当此次请求有异常时,可通过error.code获取错误码,错误码相关信息请参见错误码。示例代码如下:

    import { BusinessError } from '@kit.BasicServicesKit';
    import { paymentService } from '@kit.PaymentKit';
    import { common } from '@kit.AbilityKit';
    
    @Entry
    @Component
    struct Index {
      context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
      requestPaymentPromise() {
        // use your own orderStr
        const orderStr = '{"app_id":"***","merc_no":"***","prepay_id":"xxx","timestamp":"1680259863114","noncestr":"1487b8a60ed9f9ecc0ba759fbec23f4f","sign":"****","auth_id":"***"}';
        paymentService.requestPayment(this.context, orderStr)
          .then(() => {
            // pay success
            console.info('succeeded in paying');
          })
          .catch((error: BusinessError) => {
            // failed to pay
            console.error(`failed to pay, error.code: ${error.code}, error.message: ${error.message}`);
          });
      }
    
      build() {
        Column() {
          Button('requestPaymentPromise')
            .type(ButtonType.Capsule)
            .width('50%')
            .margin(20)
            .onClick(() => {
              this.requestPaymentPromise();
            })
          }
        .width('100%')
        .height('100%')
      }
    }
    
    

      说明:如果用户没有提前登录,系统会自动拉起华为账号登录页面让用户登录。支付成功,不建议以客户端返回作为用户的支付结果,需以服务器接收到的结果通知或者查询API返回为准。
      三、支付结果回调通知(服务器开发)
      支付成功后华为支付服务器会调用开发者提供的回调接口,将支付信息返回给开发者的服务器。
      说明:回调接口是开发者调用预下单时的入参字段callbackUrl。
      为保证信息合法性,商户服务器需要对返回的支付信息进行SM2验签,验签注意事项:
      需直接使用通知的完整内容进行验签。
      验签前需要对返回数据进行排序拼接,sign字段是签名值,排序拼接后的待验签内容需要排除sign字段。
      验签公钥使用华为支付证书。
      四、延伸和拓展
      当开发者完成上述能力之后还可以调用以下API接口完成订单相关操作。
      直连商户
      查询支付订单、申请退款、查询退款订单、查询对账单、查询结算账单。
      平台类商户/服务商
      查询支付订单、申请退款、查询退款订单、查询对账单、查询结算账单。
      本文主要引用参考HarmonyOS官方文档


      http://www.kler.cn/a/544557.html

      相关文章:

    • 2025 西湖论剑wp
    • Baumer集成一体式相机堡盟一体式相机相机如何通过NeoAPI SDK使用自动对焦功能和可分区光源控制功能(C#)
    • 【闲谈集】学网络应用开发好还是学网络安全好?
    • 【Docker】从瀑布开发到敏捷开发
    • 从零开始:Django初学者的实战之旅
    • iMC U-Center开局部署、备份方案及授权介绍
    • 像指针操作、像函数操作的类
    • 【视频总结】Deep Dive into LLMs like ChatGPT 深入探索像ChatGPT这样的大语言模型|Andrej Karpathy
    • Vulhub靶机 MinIO信息泄露漏洞(CVE-2023-28432)(渗透测试详解)
    • CPP集群聊天服务器开发实践(二):点对点聊天和添加好友
    • 【Linux】玩转Linux操作系统(十二)网络访问和管理
    • 八.springboot集成mybatis+druid数据库连接池
    • 海外服务器都有什么作用?
    • 怎么用DeepSeek批量生成抖音脚本
    • unity 0基础自学2.2:射线与button UI的使用
    • Python的秘密基地--[章节15] Python 多线程与并发编程
    • 学习总结2.13
    • Colorful/七彩虹 将星X15 AT 23 原厂Win11家庭中文版系统 带F9 Colorful一键恢复功能
    • Vue2中常用指令
    • Django创建超管用户