一文秒懂如何搭建一个最简单的充值系统

? ???阅读完本文大概需要5分钟。

目录

  • 移动支付

    • 微信支付
    • 支付宝支付
  • 充值体系
    • 最基础的架构
    • 生产环境应用
  • 总结
  • 参考

? ???一切都是生意。“天下熙熙皆为利来,天下攘攘皆为利往”。不知从什么时候起,人类社会诞生了公司这样的组织,而这个组织把人们结合在一起,产生了各种行业和商业形态,最后,公司的一切活动都变成了生意。当然,大公司有大公司的生意,小公司有小公司的买卖。

? ???过去几年saas服务软件大行其道,这其中就有大家熟悉的阿里云服务,客户注册账户+线上支付就能使用软件。

? ???线上支付,相信大家都不陌生。支付宝,微信,云闪付,苹果支付等,人人都离不开支付通道。我们看到很多大公司都有自己的支付体系和金融体系。大厂,财大气粗,有足够的投入可以自建高可用的支付体系。那么,如何中小微企业想在做点小生意,没有足够的资源自建支付体系,怎么玩?

? ???借力。这就好比大厂花了大价钱,找到水源,然后挖了一口井,小店也得活不是,给点佣金,分一股“清泉”吧。

一、移动支付
 

本文代码示例是基于威富通移动支付(https://www.swiftpass.cn/products/epay/page.html)

  1. 微信支付

? ???场景介绍

用户扫描商户展示在各种场景的二维码进行支付。:

? ???步骤1:商户根据微信支付的规则,为不同商品生成不同的二维码(如图6.1),展示在各种场景,用于用户扫描购买。

? ???步骤2:用户使用微信“扫一扫”(如图6.2)扫描二维码后,获取商品支付信息,引导用户完成支付(如图6.3)。

? ???步骤3:用户确认支付,输入支付密码(如图6.4)。

? ???步骤4:支付完成后会提示用户支付成功(如图6.5),商户后台得到支付成功的通知,然后进行发货处理。

? ???查看是否安装成功:

? ???笔者在实际项目中要使用微信扫码付款功能,开发的时候选择的是微信扫码支付的模式一(https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_4)

? ???代码片段

/// <summary>
        /// 威富通-微信支付
        /// </summary>
        /// <param name="total_fee">订单金额</param>
        /// <param name="orderno">订单号</param>
        /// <param name="productName">产品名称</param>
        private void WebChat(decimal total_fee, string orderno, string productName)
        {
            try
            {
                total_fee = total_fee * 100;//单位:分
                PayReqEntity entity = new PayReqEntity();
                entity.mch_id =“商户ID”
                string key =“KEY";//您申请的
                entity.key = key;
                entity.req_url = "https://pay.swiftpass.cn/pay/gateway";
                entity.service = "pay.weixin.native";
                entity.version = "2.0";
                entity.out_trade_no = orderno;
                entity.body = productName;
                entity.attach = "";
                entity.total_fee = Math.Round(total_fee).ToString();
                entity.time_start = "";
                entity.time_expire = "";
                entity.mch_create_ip = AppUtils.GetIp();
                entity.notify_url = ChargeHelper.BuildUrl() + "WebChat/Notify.aspx";
                WeChatPayInterface service = new WeChatPayInterface();
                PayResEntity result = service.SubmitPay(entity);
                if (!result.IsSuccess)
                {
                    string msg = result.Message;
                    if (msg.Contains("订单已存在"))
                    {
                        msg = msg + ",请重新下单!";
                    }
                    Response.Write("<script>alert('" + msg + "')</script>");
                    return;
                }
                Session["pavlue"] = result.arr;
                Response.Redirect("WebChat/Pay.aspx");
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

? ???付款完成之后,会回调WebChat/Pay.aspx页面,执行订单业务功能。

public void callback()
        {
            try
            {
                WeChatPayInterface service = new WeChatPayInterface();
                Stream stream = Request.InputStream;
                string key = "KEY";//你申请的
                NotifyResEntity result = service.PayResult(key, stream);
                if (!result.IsSuccess)
                {
                    Log.Info("[威富通-微信支付回调]:" + result.Message);
                    Response.Write("failure");
                    return;
                }
                Hashtable data = result.data;
                /*-----------交易状态------------
                 SUCCESS—支付成功
                 REFUND—转入退款
                 NOTPAY—未支付
                 CLOSED—已关闭
                 PAYERROR—支付失败(其他原因,如银行返回失败)
                 ------------------------------------ */
                string out_trade_no = data["out_trade_no"].ToString();//商户订单号
                int status = Convert.ToInt32(data["status"]);//返回状态码(0表示成功,非0表示失败此字段是通信标识,非交易标识,交易是否成功需要查看 result_code 来判断)
                int result_code = Convert.ToInt32(data["result_code"]);//业务结果(0表示成功,非0表示失败)
                if (status == 0 && result_code == 0)
                {
                    string total_fee = data["total_fee"].ToString();//总金额,以分为单位,不允许包含任何字、符号
                    string transaction_id = data["transaction_id"].ToString();//平台交易单号
                    //此处可以在添加相关处理业务 ,更新数据库表中的记录。
                    int proxyid = 0;
                    string bankbill = "";
                    ulong employeeid = 1;
                    string comment = "微信支付";
                    string billtype = "正常订单";
                    int payment = 24;//微信支付
                    string bankname = "";
                    string payer = "";
                    string orderno = out_trade_no;
                    string taobaopayno = transaction_id;
                    decimal amountpaid = 0;
                    if (!string.IsNullOrEmpty(total_fee))
                    {
                        amountpaid = Convert.ToDecimal(total_fee) / 100;
                    }

                    //TODO:业务处理部分
                    Response.Write("success");
                    return;

                }
                else
                {
                    Log.Info("[威富通-微信支付回调]:商户订单号out_trade_no=" + out_trade_no + "状态码status=" + status + ",业务结果result_code=" + result_code);
                }
            }
            catch (Exception ex)
            {
                Log.Info("[威富通-微信支付回调]异常:" + ex);
            }
            Response.Write("failure");
        }

2.支付宝支付

? ???场景介绍

????扫码支付,指用户打开支付宝钱包中的“扫一扫”功能,扫描商户针对每个订单实时生成的订单二维码,并在手机端确认支付。

? ???调用流程

https://docs.open.alipay.com/194/105170/

????商户系统调用支付宝预下单接口alipay.trade.precreate,获得该订单二维码图片地址。
????发起轮询获得支付结果:等待5秒后调用交易查询接口alipay.trade.query通过支付时传入的商户订单号(out_trade_no)查询支付结果(返回参数TRADE_STATUS),如果仍然返回等待用户付款(WAIT_BUYER_PAY),则再次等待5秒后继续查询,直到返回确切的支付结果(成功TRADE_SUCCESS 或 已撤销关闭TRADE_CLOSED),或是超出轮询时间。在最后一次查询仍然返回等待用户付款的情况下,必须立即调用交易撤销接口alipay.trade.cancel将这笔交易撤销,避免用户继续支付。
????除了主动轮询,也可以通过接受异步通知获得支付结果,详见扫码异步通知,注意一定要对异步通知做验签,确保通知是支付宝发出的。

代码片段:

 private void Alipay(decimal total_fee, string orderno, string productName)
        {
            total_fee = total_fee * 100;//单位:分
            PayReqEntity entity = new PayReqEntity();
            entity.mch_id = "商户ID";
            string key = 商户Key"";
            entity.key = key;
            entity.req_url = "https://pay.swiftpass.cn/pay/gateway";
            entity.service = "pay.alipay.native";
            entity.version = "2.0";
            entity.out_trade_no = orderno;
            entity.body = productName;
            entity.attach = "";
            entity.total_fee = Math.Round(total_fee).ToString();
            entity.time_start = "";
            entity.time_expire = "";
            entity.mch_create_ip = AppUtils.GetIp();
            entity.notify_url = ChargeHelper.BuildUrl() + "Alipay/Notify.aspx";
            WeChatPayInterface service = new WeChatPayInterface();
            PayResEntity result = service.SubmitPay(entity);
            if (!result.IsSuccess)
            {
                string msg = result.Message;
                if (msg.Contains("订单已存在"))
                {
                    msg = msg + ",请重新下单!";
                }
                Response.Write("<script>alert('" + msg + "')</script>");
                return;
            }
            Session["alipay_pavlue"] = result.arr;
            Response.Redirect("Alipay/Pay.aspx");
        }

????支付完成,同样回调Alipay/Pay.aspx

public void callback()
        {
            try
            {
                WeChatPayInterface service = new WeChatPayInterface();
                Stream stream = Request.InputStream;
                string key = "KEY";//填写自己的
                NotifyResEntity result = service.PayResult(key, stream);
                if (!result.IsSuccess)
                {
                    Log.Info("[威富通-支付宝支付回调]:" + result.Message);
                    Response.Write("failure");
                    return;
                }
                Hashtable data = result.data;
                /*-----------交易状态------------
                 SUCCESS—支付成功
                 REFUND—转入退款
                 NOTPAY—未支付
                 CLOSED—已关闭
                 PAYERROR—支付失败(其他原因,如银行返回失败)
                 ------------------------------------ */
                //string trade_state = data["trade_state"].ToString();
                string out_trade_no = data["out_trade_no"].ToString();//商户订单号
                int status = Convert.ToInt32(data["status"]);//返回状态码(0表示成功,非0表示失败此字段是通信标识,非交易标识,交易是否成功需要查看 result_code 来判断)
                int result_code = Convert.ToInt32(data["result_code"]);//业务结果(0表示成功,非0表示失败)
                if (status == 0 && result_code == 0)
                {
                    string total_fee = data["total_fee"].ToString();//总金额,以分为单位,不允许包含任何字、符号
                    string transaction_id = data["transaction_id"].ToString();//平台交易单号
                    //此处可以在添加相关处理业务 ,更新数据库表中的记录。
                    int proxyid = 0;
                    string bankbill = "";
                    ulong employeeid = 1;
                    string comment = "支付宝支付";
                    string billtype = "正常订单";
                    int payment = 23;//威富通-支付宝支付
                    string bankname = "";
                    string payer = "";
                    string orderno = out_trade_no;
                    string taobaopayno = transaction_id;
                    decimal amountpaid = 0;
                    if (!string.IsNullOrEmpty(total_fee))
                    {
                        amountpaid = Convert.ToDecimal(total_fee) / 100;
                    }
                    //TODO:业务处理部分
                    Response.Write("success");
                    return;
                }
                else
                {
                    Log.Info("[威富通-支付宝支付回调]:商户订单号out_trade_no=" + out_trade_no + "状态码status=" + status + ",业务结果result_code=" + result_code);
                }
            }
            catch (Exception ex)
            {
                Log.Info("[威富通-支付宝支付回调]异常:" + ex);
            }
            Response.Write("failure");
        }


二、充值体系

任何一家公司做生意的都会使用支付业务,这里以SAAS行业支付为例。

  • 最基本的充值业务架构

    满足一下基本需求

    • 用户账户中心
    • 用户可充值,可查看订单和购买商品
    • 代理商、销售等营销部门可以查看业绩报表

  • 订单生成流程

? ???在实际生产环境中中,订单的流程也是较为重要的一环。

  • 防止重复支付

? ???支付完成,回调的时候检测订单状态。已支付的就不再执行。

  • 如何保证支付一致性

? ???在实际生产环境中中,总会发生支付接口支付成功,回调执行订单业务失败的情况,简单的办法是可以增加一个单独检查业务,定时对不一致的订单进行二次执行。

三、总结

? ???基本的充值体系是通用的。订单业务量大的可以增加消息队列处理。在保证一致性方面,我们在该架构上还有很多细节可以完善。

四、参考

? ???个人微信公众号:

原文地址:https://www.cnblogs.com/lucky_hu/p/9823406.html

时间: 2024-08-30 01:59:25

一文秒懂如何搭建一个最简单的充值系统的相关文章

Selenium+java - 手把手一起搭建一个最简单自动化测试框架

写在前面 我们刚开始做自动化测试,可能写的代码都是基于原生写的代码,看起来特别不美观,而且感觉特别生硬. 来看下面一段代码,如下图所示: 从上面图片代码来看,具体特征如下: driver对象在测试类中显示 定位元素的value值在测试类中显示 定位元素的方式(By对象)在测试类中显示 代码一报错,还要去测试类里面找是哪段代码报错,要是代码行数几百行时呢,就不好定位问题了 这样的测试脚本组装批量执行,批量报错后,怒号排查,定位问题,很吃力 看看自己有几条命中呢,其他现象就不一一列举了. 1.为什么

Dubbo入门---搭建一个最简单的Demo框架

Dubbo背景和简介 Dubbo开始于电商系统,因此在这里先从电商系统的演变讲起. 单一应用框架(ORM) 当网站流量很小时,只需一个应用,将所有功能如下单支付等都部署在一起,以减少部署节点和成本. 缺点:单一的系统架构,使得在开发过程中,占用的资源越来越多,而且随着流量的增加越来越难以维护 垂直应用框架(MVC) 垂直应用架构解决了单一应用架构所面临的扩容问题,流量能够分散到各个子系统当中,且系统的体积可控,一定程度上降低了开发人员之间协同以及维护的成本,提升了开发效率. 缺点:但是在垂直架构

搭建一个超级简单的spring框架

1.准备环境 (1)下载JDK.myEclipse.Tomcat,之后配置好相关的参数 备注:在myEclipse上配置Tomcat: 启动Tomcat服务后,在浏览器输入localhost:8080运行成功即表示配置成功 (2)新建一个Web Project 配置到Tomcat上 再次启动Tomcat,输入地址后,如果能运行成功即表示新建成功 2.前期准备 (1)首先下载所需要的jar包 下载地址: spring-framework-4.0.4.RELEASE-dist:http://repo

如何快速搭建一个完整的移动直播系统?

移动直播行业的火热会在很长一段时间内持续,通过和各行业的整合,从而成为具有无限可能性的行业.主要因为以下三个原因: 第一,移动直播的UGC生产模式比PC端的直播更明显,人人都有设备,随时随地开播,完全顺应了互联网时代的开放性原则,能刺激更多人去创造和传播优质内容. 第二,网络带宽和速度在逐渐提高,网络成本在逐渐下降,为移动直播提供一个极佳的发展环境.文字.声音.视频.游戏等都会在移动直播中呈现,创造出更加丰富的用户体验.直播可以以SDK的形式接入到自己的应用中,比如,教育领域中的课后辅导完全可以

利用SpringCloud搭建一个最简单的微服务框架

http://blog.csdn.net/caicongyang/article/details/52974406 1.微服务 微服务主要包含服务注册,服务发现,服务路由,服务配置,服务熔断,服务降级等一系列的服务,而Spring Cloud为我们提供了个一整套的服务: 本例子为你提供了最简单的一个服务发现例子,包含服务注册发现spingCloudEurekaServer.服务配置中心spingCloudConfServer.以及一个app应用springCloudApp 2.服务注册与发现 s

VPS -Digital Ocean -搭建一个最简单的web服务器

简单的也是美的 在一个目录放自己的几个showcase网页方便和别人分享,最简单的方式是什么 创建文件夹,放入自己的网页文件 在目录下执行 $ nohup python -m SimpleHTTPServer & 这样当你关闭session的时候这个服务器还在运行. 参考文献: http://unix.stackexchange.com/questions/479/keep-ssh-sessions-running-after-disconnection http://askubuntu.com

【实战】如何亲手搭建一个分布式 IM(即时通讯) 系统

前言 老读者应该还记得我之前分享过一篇<设计一个百万级的消息推送系统>:虽然我在文中有贴一些伪代码,依然有些朋友希望能直接分享一些可以运行的源码:这么久了是时候把坑填上了. 目录结构: 本文较长,高能预警:带好瓜子板凳. 于是在之前的基础上我完善了一些内容,先来看看这个项目的介绍吧: CIM(CROSS-IM) 一款面向开发者的 IM(即时通讯)系统:同时提供了一些组件帮助开发者构建一款属于自己可水平扩展的 IM . 借助 CIM 你可以实现以下需求: IM 即时通讯系统. 适用于 APP 的

如何搭建一个完整的视频直播系统?

朋友打算打造一个全新模式的视频直播平台,主要功能有些类似现在很多的美女直播平台.假设前期同时在线观看人数为2W人,清晰度不低于720P,拥有美颜.混音等附加功能,还有最重要的不能卡顿.如果以上假设成立,需要做哪些准备工作,技术门槛有多高,资金支出要多少? 视频直播,可以分为 采集,前处理,编码,传输,解码,渲染 这几个环节,下面分别说下: 采集,iOS是比较简单的,Android则要做些机型适配工作,PC最麻烦各种奇葩摄像头驱动,出了问题特别不好处理,建议放弃PC只支持手机主播,目前几个新进的直

用python3.x与mysql数据库构建简单的爬虫系统(转)

这是在博客园的第一篇文章,由于本人还是一个编程菜鸟,也写不出那些高大上的牛逼文章,这篇文章就是对自己这段时间学习python的一个总结吧. 众所周知python是一门对初学编程的人相当友好的编程语言,就像本屌丝一样,一学就对它产生好感了!当然,想要精通它还有很多东西需要学习.那废话不多说了,下面我就来说一下如何用python3.x与mysql数据库构建一个简单的爬虫系统(其实就是把从网页上爬下来的内容存储到mysql数据库中). 首先就是搭建环境了,这里就简介绍一下我的环境吧.本机的操作系统是w