美文网首页
微信扫码支付的简单实现

微信扫码支付的简单实现

作者: 水手_surge | 来源:发表于2016-11-07 23:20 被阅读299次

    朋友要帮忙写一个ARM上可用的微信扫码支付的DEMO以便应用到他的系统上去,而张大神只给了JAVA,C#和PHP的DEMO,没办法,只能自己用QT来写了,而我的QT等级可怜到只是知道有QT这门语言。。。
    我们先来简单了解一下扫码支付的模式

    【模式一】:商户后台系统根据微信支付规则链接生成二维码,链接中带固定参数productid(可定义为产品标识或订单号)。用户扫码后,微信支付系统将productid和用户唯一标识(openid)回调商户后台系统(需要设置支付回调URL),商户后台系统根据productid生成支付交易,最后微信支付系统发起用户支付流程。
    【模式二】:商户后台系统调用微信支付【统一下单API】生成预付交易,将接口返回的链接生成二维码,用户扫码后输入密码完成支付交易。注意:该模式的预付单有效期为2小时,过期后无法支付。--微信支付

    需要实现的目标是模式二,那我们可以细分成以下步骤:
    1.调用微信支付生成预付费
    2.将接口返回的链接生成二维码
    3.用户扫码支付

    OK,我对于这个DEMO的做法就是,把任务拆分成不可拆分的部分,然后实现它。对于QT我也不太了解,看了微信的文档,要生成预付费交易要完成以下几个部分
    -字典转换为XML
    -XML转换为字典
    -通过HTTPS,向服务器发送一个POST的请求,接收返回数据并生成二维码
    至于后面的部分,就是进入到支付环节了,我们在这里不考虑。

    而需要将字典与XML之间转换,我是这么做的

    
    class WxPayData
    {
    public:
     WxPayData();
    
     //采用排序的Dictionary的好处是方便对数据包进行签名,不用再签名之前再做一次排序
     QMap<QString,QString> myMap;
    
     /*
     * 设置某个字段的值
     * @param key 字段名
     * @param value 字段值
     */
     void SetValue(QString key, QString value);
    
     /*
     * 根据字段名获取某个字段的值
     * @param key 字段名
     * @return key对应的字段值
     */
     QString GetValue(QString key);
    
     /*
     * 判断某个字段是否已设置
     * @param key 字段名
     * @return 若字段key已被设置,则返回true,否则返回false
     */
     bool IsSet(QString key);
    
     /*
     * @将Dictionary转成xml
     * @return 经转换得到的xml串
     * @throws WxPayException
     **/
     QString ToXml(void);
    
     /*
     * @将xml转为WxPayData对象并返回对象内部的数据
     * @param QString 待转换的xml串
     * @return 经转换得到的Dictionary
     * @throws WxPayException
     */
     QMap<QString,QString>FromXml(QString xml);
    
    };
    

    类的实现

    #include "wxpaydata.h"
    #include <QtXml/QDomDocument>
    #include <QMessageBox>
    
    WxPayData::WxPayData()
    {
    }
    /*
    * 设置某个字段的值
    * @param key 字段名
     * @param value 字段值
    */
     void WxPayData::SetValue(QString key, QString value)
    {
     myMap[key] = value;
    }
    
    /*
    * 根据字段名获取某个字段的值
    * @param key 字段名
     * @return key对应的字段值
    */
    QString WxPayData::GetValue(QString key)
    {
     QString str = myMap.value(key);
     return str;
    }
    
    /*
     * 判断某个字段是否已设置
     * @param key 字段名
     * @return 若字段key已被设置,则返回true,否则返回false
     */
    bool WxPayData::IsSet(QString key)
    {
     QString str = myMap.value(key);
     if (str.isEmpty())
     return true;
     else
     return false;
    }
    
    /*
    * @将Dictionary转成xml
    * @return 经转换得到的xml串
    * @throws WxPayException
    */
    QString WxPayData::ToXml(void)
    {
     QString xml = "<xml>";
     QMap<QString,QString>::iterator i; //遍历map
     for ( i = myMap.begin(); i != myMap.end(); ++i )
     {
     if(i.value().isNull())
     {
     throw QString("WxPayData内部含有值为null的字段!");
     }
    
     if(i.key() == "detail")
     {
     xml += "<" + i.key() + ">" + "<![CDATA[" + i.value() + "]]></" + i.key() + ">";
     }
     else
     {
     xml += "<" + i.key() + ">" + i.value() + "</" + i.key() + ">";
     }
     }
    
     return xml + "</xml>";
    }
    
    /*
    * @将xml转为WxPayData对象并返回对象内部的数据
    * @param string 待转换的xml串
    * @return 经转换得到的Dictionary
    * @throws WxPayException
    */
    QMap<QString,QString> WxPayData::FromXml(QString xml)
    {
       QDomDocument doc;
       QDomElement root = doc.documentElement();
    
     if(xml.isEmpty() || xml.isNull())
     {
       throw QString("将空的xml串转换为WxPayData不合法!");
     }
    
     for (QDomNode node = root.firstChild(); !node.isNull(); node = node.nextSibling())
     {
       QDomElement element = node.toElement();
       myMap[element.tagName()] = element.text().replace("\"","");
     }
    
    
     //2015-06-29 错误是没有签名
     if(myMap["return_code"] != "SUCCESS")
     {
       return myMap;
     }
     CheckSign();//验证签名,不通过会抛异常
    
     return myMap;
    }
    

    相关文章

      网友评论

          本文标题:微信扫码支付的简单实现

          本文链接:https://www.haomeiwen.com/subject/letauttx.html