安全与便捷并行,打造高效易用的用户支付体验

在当今数字时代,快捷、安全的支付方式已经成为用户日常生活中不可或缺的一部分。不论是在线购物、订阅服务,还是线下消费,用户都期望享受流畅且安全的支付体验。作为开发者,选择适合的支付服务不仅关乎用户体验,更直接影响业务是否能够达到预期的成功。

HarmonyOS SDK 华为支付服务(Payment Kit) 提供了方便、安全和快捷的支付方式,将强大的支付、营销、运营等能力,通过HarmonyOS系统级接口形式开放给广大开发者,集成便捷且快速,为用户提供最佳的支付解决方案。用户可以在App或者元服务内,通过华为支付服务的单次支付完成实体商品或服务的购买。以下我们以单次支付为例深入了解下华为支付服务的接入流程。

业务流程

开发步骤

注:商户及应用开发前置准备事宜请参考接入指南,本文仅阐述关键开发步骤。

预下单(服务器开发)

1.开发者按照商户模型调用直连商户预下单或平台类商户/服务商预下单接口获取预支付ID(prepayId)。

为保证支付订单的安全性和可靠性需要对请求body和请求头PayMercAuth对象内的入参排序拼接进行签名。请参考排序拼接和签名示例代码。

2.构建orderStr。

商户服务器需要将客户端支付接口入参orderStr签名后返回给客户端。

import com.huawei.petalpay.paymentservice.apiservice.client.model.BaseGwRspWithSign;
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:实物商品购买,100003:预付类账号充值,100004:航旅交通服务,100005:活动票务订购,100006:商业服务消费,100007:生活服务消费,100008:租金缴纳,100009:会员费缴纳,100011:其他商家消费,100037:公共便民服务).totalAmount(2L).callbackUrl("https://www.xxxxxx.com/hw/pay/callback") // 回调通知地址,通知URL必须为直接可访问的URL,要求为https地址。最大长度为512。请替换为格式正确的结果通知回调地址。.build();}
}
拉起华为支付收银台(端侧开发)

调用requestPayment接口拉起Payment Kit支付收银台。

•当接口通过then()返回时,则表示当前订单支付成功。

•当此次请求有异常时,可通过error.code获取错误码,错误码请参见错误码。

import { BusinessError } from '@kit.BasicServicesKit';
import { paymentService } from '@kit.PaymentKit';
import { common } from '@kit.AbilityKit';
[@Entry](https://my.oschina.net/u/4127701)
[@Component](https://my.oschina.net/u/3907912)
struct Index {context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;requestPaymentPromise() {// use your own orderStrconst orderStr = '{\'app_id\':\'***\',\'merc_no\':\'***\',\'prepay_id\':\'xxx\',\'timestamp\':\'1680259863114\',\'noncestr\':\'1487b8a60ed9f9ecc0ba759fbec23f4f\',\'sign\':\'****\',\'auth_id\':\'***\'}';paymentService.requestPayment(this.context, orderStr).then(() => {// pay successconsole.info('succeeded in paying');}).catch((error: BusinessError) => {// failed to payconsole.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%')}
}
支付结果回调通知(服务器开发)

支付成功后Payment Kit服务器会调用开发者提供的回调接口,将支付信息返回给开发者的服务器,回调详细信息按商户模式请参见直连商户支付结果回调通知或平台类商户/服务商支付结果回调通知。

为保证信息合法性,商户服务器需要对返回的支付信息进行SM2验签,验签注意事项:

1.需直接使用通知的完整内容进行验签。

2.验签前需要对返回数据进行排序拼接,sign字段是签名值,排序拼接后的待验签内容需要排除sign字段。

3.验签公钥使用华为支付证书。

了解更多详情>>

访问华为支付服务联盟官网

获取华为单次支付功能开发指导文档

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/381626.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

开源模型应用落地-FastAPI-助力模型交互-进阶篇-中间件(四)

一、前言 FastAPI 的高级用法可以为开发人员带来许多好处。它能帮助实现更复杂的路由逻辑和参数处理,使应用程序能够处理各种不同的请求场景,提高应用程序的灵活性和可扩展性。 在数据验证和转换方面,高级用法提供了更精细和准确的控制&#…

【优秀设计案例】基于K-Means聚类算法的球员数据聚类分析设计与实现

背景及意义 随着NBA比赛的日益竞争激烈,球队需要更加深入地了解球员的能力和特征,以制定更有效的战术和球队管理策略。而NBA球员的统计数据包含了大量有价值的信息,通过对这些数据进行聚类分析,可以揭示出球员之间的相似性和差异…

套接字编程一(简单的UDP网络程序)

文章目录 一、 理解源IP地址和目的IP地址二、 认识端口号1. 理解 "端口号" 和 "进程ID"2. 理解源端口号和目的端口号 三、 认识协议1. 认识TCP协议2. 认识UDP协议 四、 网络字节序五、 socket编程接口1. socket 常见API2. sockaddr结构(1&#…

Leetcode1688. 比赛中的配对次数

问题描述: 给你一个整数 n ,表示比赛中的队伍数。比赛遵循一种独特的赛制: 如果当前队伍数是 偶数 ,那么每支队伍都会与另一支队伍配对。总共进行 n / 2 场比赛,且产生 n / 2 支队伍进入下一轮。如果当前队伍数为 奇…

如何获得Cesium的TileSet并设置本地服务器的Url

一.总体思路 首先使用管理者获得TileSet,通过JSON文件读写,调用对应的Cesium内部提供的函数。 UE5中Json文件的读取与解析 - 知乎 (zhihu.com) 不太了解JSON的可以学习这个。 二.具体实现 1.创建Actor,并且 如何获得Cesium的TileSet,设置本地Url 一…

PHP连接MySQL数据库

PHP本身不具备操作MySQL数据库的能力,需要借助MySQL扩展来实现。 1、PHP加载MySQL扩展:php.ini文件中。(不要用记事本打开) 2、PHP中所有扩展都是在ext的文件夹中,需要指定扩展所在路径:extension_dir。 3、…

Vue项目实现单点登录(SSO)的逻辑和基本流程

项目集群如果一个一个登录会非常麻烦,尤其是一些大企业或者多项目使用一套体系数据的环境中,这时候登录中心也就应用而生, 今天简单说一下vue sso的实现思路,vue项目实现单点登录(SSO)通常涉及以下几个步骤…

【数据结构】排序算法——Lessen1

Hi~!这里是奋斗的小羊,很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~~ 💥💥个人主页:奋斗的小羊 💥💥所属专栏:C语言 🚀本系列文章为个人学习…

防御保护课-防火墙接口配置实验

一、实验拓扑 (我做实验用的图如下) 二、实验要求 1.防火墙向下使用子接口分别对应生产区和办公区 2.所有分区设备可以ping通网关 三、实验思路 配IP; 划分vlan并配置vlan; 配置路由和安全策略。 四、实验配置 1、画图并…

【引领未来智造新纪元:量化机器人的革命性应用】

在日新月异的科技浪潮中,量化机器人正以其超凡的智慧与精准的操作,悄然改变着各行各业的生产面貌,成为推动产业升级、提升竞争力的关键力量。今天,让我们一同探索量化机器人在不同领域的广泛应用价值,见证它如何以科技…

相对定位语法:css+xpath基础语法使用-定位页面元素

文章目录 CSS相对定位获取元素关系定位顺序关系 XPath相对定位基础语法顺序关系-通过索引获取元素选取元素 总结 ✨✨✨学习的道路很枯燥,希望我们能并肩走下来! 编程真是一件很奇妙的东西。你只是浅尝辄止,那么只会觉得枯燥乏味&#xff0c…

python基础语法 007 文件操作-2文件支持模式文件的内置函数

1.3 文件支持的模式 模式含义ropen a file for reading(default)wopen a file for writing,creates a new file if it does not exist or truncates the file if it exists x open a file foe exclusive creation. if the file already exists, the operation fails.独创模式&…

数据结构day4

一、思维导图 二、课后练习 头文件 #ifndef LINKLIST_H #define LINKLIST_H #include <myhead.h>//定义数据类型 typedef int datatype;//定义节点类型 typedef struct Node {union{int len; //头结点数据域datatype data; //普通节点数据域};struct Node *next; …

PyTorch 深度学习实践-处理多维特征的输入

视频指路 参考博客笔记 参考笔记二 通过多个线性模型来模拟非线性的空间变换&#xff0c;矩阵计算就是不同维度之间的空间转换 说明&#xff1a;1、乘的权重(w)都一样&#xff0c;加的偏置(b)也一样。b变成矩阵时使用广播机制。神经网络的参数w和b是网络需要学习的&#xff0c…

浏览器跨tab页面通信方式总结

需求&#xff1a; 浏览器不同 tab 标签页之间是独立的&#xff0c; 如果要通信必须通过特殊手段来实现跨标签页通信。 1.StorageEvent 事件 当一个标签页 localStorage 变化时&#xff08;sessionStorage 无效&#xff09;&#xff0c;同源下另一个或其他所有标签页使用 DO…

buuctf web 第五到八题

[ACTF2020 新生赛]Exec 这里属实有点没想到了&#xff0c;以为要弹shell&#xff0c;结果不用 127.0.0.1;ls /PING 127.0.0.1 (127.0.0.1): 56 data bytes bin dev etc flag home lib media mnt opt proc root run sbin srv sys tmp usr var127.0.0.1;tac /f*[GXYCTF2019]Pin…

React的usestate设置了值后马上打印获取不到最新值

我们在使用usestate有时候设置了值后&#xff0c;我们想要更新一些值&#xff0c;这时候&#xff0c;我们要想要马上获取这个值去做一些处理&#xff0c;发现获取不到&#xff0c;这是为什么呢&#xff1f; 效果如下&#xff1a; 1、原因如下 在React中,当你使用useState钩子…

设计模式11-原型模式

设计模式11-原型模式 写在前面对象创建模式典型模式原型模式动机结构代码推导应用特点要点总结 原型模式与工厂方法模式对比工厂方法模式原型模式什么时候用什么模式 写在前面 对象创建模式 通过对象创建模式绕开动态内存分配来避免创建过程中所导致的耦合过紧的问题。从而支…

谷粒商城实战笔记-40-前端基础-Vue-计算属性、监听器、过滤器

文章目录 一&#xff0c;计算属性1&#xff0c;用途2&#xff0c;用法2.1 定义View2.2 声明计算属性 3&#xff0c;注意事项 二&#xff0c;监听器1. 使用 watch 监听属性的变化 三&#xff0c;过滤器1&#xff0c;定义局部过滤器2&#xff0c;定义全局过滤器3&#xff0c;使用…

GraphPad prism处理cck-8获得ic50

C组为空白对照组&#xff0c;a组为dmso对照组&#xff0c;b组为细胞加药组&#xff0c;八个梯度的药物浓度 一、数据转化 首先&#xff0c;打开软件&#xff0c;选项中选择x的第一项&#xff0c;y的第二项&#xff0c;单一药物浓度设定了几个孔就选几 把自己的药物浓度直接复制…