藉助小程序雲開發實現小程序支付功能(含源碼)

咱們在作小程序支付相關的開發時,總會遇到這些難題。小程序調用微信支付時,必需要有本身的服務器,有本身的備案域名,有本身的後臺開發。這就致使咱們作小程序支付時的成本很大。本節就來教你們如何使用小程序雲開發實現小程序支付功能的開發。不用搭建本身的服務器,不用有本身的備案域名。只須要簡簡單單的使用小程序雲開發。html

老規矩先看效果圖: node

本節知識點

1,雲開發的部署和使用 2,支付相關的雲函數開發 3,商品列表 4,訂單列表 5,微信支付與支付成功回調數據庫

支付成功給用戶發送推送消息的功能會在後面講解。小程序

下面就來教你們如何藉助雲開發使用小程序支付功能。

支付所須要用到的配置信息

1,小程序appid 2,雲開發環境id 3,微信商戶號 4,商戶密匙微信小程序

一,準備工做

1,已經申請小程序,獲取小程序 AppID 和 Secret 在小程序管理後臺中,【設置】 →【開發設置】 下能夠獲取微信小程序 AppID 和 Secret。 安全

2,微信支付商戶號,獲取商戶號和商戶密鑰在微信支付商戶管理平臺中,【帳戶中心】→【商戶信息】 下能夠獲取微信支付商戶號。
在【帳戶中心】 ‒> 【API安全】 下能夠設置商戶密鑰。
這裏特殊說明下,我的小程序是沒有辦法使用微信支付的。因此若是想使用微信支付功能,必須是非我的帳號(固然我的能夠辦個體戶工商執照來註冊非我的小程序帳號)

3,微信開發者 IDE developers.weixin.qq.com/miniprogram… 4,開通小程序雲開發功能:edu.csdn.net/course/play…bash

二,商品列表的實現

效果圖以下,因爲本節重點是支付的實現,因此這裏只簡單貼出關鍵代碼。 服務器

wxml佈局以下:

<view class="container">
  <view class="good-item" wx:for="{{goods}}" wx:key="*this" ontap="getDetail" data-goodid="{{item._id}}">
    <view class="good-image">
      <image src="{{pic}}"></image>
    </view>
    <view class="good-detail">
      <view class="title">商品: {{item.name}}</view>
      <view class="content">價格: {{item.price / 100}} 元 </view>
      <button
        class="button"
        type="primary"
        bindtap="makeOrder"
        data-goodid="{{item._id}}"
      >下單</button>
    </view>
  </view>
</view>
複製代碼

咱們所須要作的就是藉助雲開發獲取雲數據庫裏的商品信息,而後展現到商品列表,關於雲開發獲取商品列表並展現本節不作講解(感興趣的同窗能夠翻看個人歷史博客,有寫過的) 微信

三,支付雲函數的建立

首先看下咱們支付雲函數都包含那些內容 微信開發

簡單先講解下每一個的用處 config下的index.js是作支付配置用的,主要配置支付相關的帳號信息 lib是用的第三方的支付庫,這裏不作講解。 重點講解的是雲函數入口 index.js

下面就來教你們如何去配置

1,配置config下的index.js, 這一步所須要作的就是把小程序appid,雲開發環境ID,商戶id,商戶密匙。填進去。

2,配置入口雲函數
詳細代碼以下,代碼裏註釋很清除了,這裏再也不作單獨講解:

const cloud = require('wx-server-sdk')
cloud.init()

const app = require('tcb-admin-node');
const pay = require('./lib/pay');
const {
 mpAppId,
 KEY
} = require('./config/index');
const {
 WXPayConstants,
 WXPayUtil
} = require('wx-js-utils');
const Res = require('./lib/res');
const ip = require('ip');

/**
 *
 * @param {obj} event
 * @param {string} event.type 功能類型
 * @param {} userInfo.openId 用戶的openid
 */
exports.main = async function(event, context) {
 const {
  type,
  data,
  userInfo
 } = event;
 const wxContext = cloud.getWXContext()
 const openid = userInfo.openId;
 
 app.init();
 const db = app.database();
 const goodCollection = db.collection('goods');
 const orderCollection = db.collection('order');

 // 訂單文檔的status 0 未支付 1 已支付 2 已關閉
 switch (type) {
  // [在此處放置 unifiedorder 的相關代碼]
  case 'unifiedorder':
   {
    // 查詢該商品 ID 是否存在於數據庫中,並將數據提取出來
    const goodId = data.goodId
    let goods = await goodCollection.doc(goodId).get();

    if (!goods.data.length) {
     return new Res({
      code: 1,
      message: '找不到商品'
     });
    }

    // 在雲函數中提取數據,包括名稱、價格才更合理安全,
    // 由於從端裏傳過來的商品數據都是不可靠的
    let good = goods.data[0];

    // 拼湊微信支付統一下單的參數
    const curTime = Date.now();
    const tradeNo = `${goodId}-${curTime}`;
    const body = good.name;
    const spbill_create_ip = ip.address() || '127.0.0.1';
    // 雲函數暫不支付 http 觸發器,所以這裏回調 notify_url 能夠先隨便填。
    const notify_url = 'http://www.qq.com'; //'127.0.0.1';
    const total_fee = good.price;
    const time_stamp = '' + Math.ceil(Date.now() / 1000);
    const out_trade_no = `${tradeNo}`;
    const sign_type = WXPayConstants.SIGN_TYPE_MD5;

    let orderParam = {
     body,
     spbill_create_ip,
     notify_url,
     out_trade_no,
     total_fee,
     openid,
     trade_type: 'JSAPI',
     timeStamp: time_stamp,
    };

    // 調用 wx-js-utils 中的統一下單方法
    const {
     return_code,
     ...restData
    } = await pay.unifiedOrder(orderParam);

    let order_id = null;

    if (return_code === 'SUCCESS' && restData.result_code === 'SUCCESS') {
     const {
      prepay_id,
      nonce_str
     } = restData;

     // 微信小程序支付要單獨進地簽名,並返回給小程序端
     const sign = WXPayUtil.generateSignature({
      appId: mpAppId,
      nonceStr: nonce_str,
      package: `prepay_id=${prepay_id}`,
      signType: 'MD5',
      timeStamp: time_stamp
     }, KEY);

     let orderData = {
      out_trade_no,
      time_stamp,
      nonce_str,
      sign,
      sign_type,
      body,
      total_fee,
      prepay_id,
      sign,
      status: 0, // 訂單文檔的status 0 未支付 1 已支付 2 已關閉
      _openid: openid,
     };

     let order = await orderCollection.add(orderData);

     order_id = order.id;
    }

    return new Res({
     code: return_code === 'SUCCESS' ? 0 : 1,
     data: {
      out_trade_no,
      time_stamp,
      order_id,
      ...restData
     }
    });
   }
   // [在此處放置 payorder 的相關代碼]
  case 'payorder':
   {
    // 從端裏出來相關的訂單相信
    const {
     out_trade_no,
     prepay_id,
     body,
     total_fee
    } = data;

    // 到微信支付側查詢是否存在該訂單,並查詢訂單狀態,看看是否已經支付成功了。
    const {
     return_code,
     ...restData
    } = await pay.orderQuery({
     out_trade_no
    });

    // 若訂單存在並支付成功,則開始處理支付
    if (restData.trade_state === 'SUCCESS') {
     let result = await orderCollection
      .where({
       out_trade_no
      })
      .update({
       status: 1,
       trade_state: restData.trade_state,
       trade_state_desc: restData.trade_state_desc
      });


     let curDate = new Date();
     let time = `${curDate.getFullYear()}-${curDate.getMonth() +
          1}-${curDate.getDate()} ${curDate.getHours()}:${curDate.getMinutes()}:${curDate.getSeconds()}`;

   

    }

    return new Res({
     code: return_code === 'SUCCESS' ? 0 : 1,
     data: restData
    });
   }
  case 'orderquery':
   {
    const {
     transaction_id,
     out_trade_no
    } = data;
    // 查詢訂單

    const {
     data: dbData
    } = await orderCollection
    .where({
     out_trade_no
    })
    .get();

    const {
     return_code,
     ...restData
    } = await pay.orderQuery({
     transaction_id,
     out_trade_no
    });

    return new Res({
     code: return_code === 'SUCCESS' ? 0 : 1,
     data: { ...restData,
      ...dbData[0]
     }
    });
   }

  case 'closeorder':
   {
    // 關閉訂單
    const {
     out_trade_no
    } = data;
    const {
     return_code,
     ...restData
    } = await pay.closeOrder({
     out_trade_no
    });
    if (return_code === 'SUCCESS' &&
     restData.result_code === 'SUCCESS') {
     await orderCollection
      .where({
       out_trade_no
      })
      .update({
       status: 2,
       trade_state: 'CLOSED',
       trade_state_desc: '訂單已關閉'
      });
    }

    return new Res({
     code: return_code === 'SUCCESS' ? 0 : 1,
     data: restData
    });
   }
 }
}
複製代碼

其實咱們支付的關鍵功能都在上面這些代碼裏面了。

再來看下,支付的相關流程截圖

上圖就涉及到了咱們的訂單列表,支付狀態,支付成功後的回調。 今天就先講到這裏,後面會繼續給你們講解支付的其餘功能。好比支付成功後的消息推送,也是能夠藉助雲開發實現的。

因爲源碼裏涉及到一些私密信息,這裏就不單獨貼出源碼下載連接了,你們感興趣的話,能夠私信我,或者在底部留言。單獨找我要源碼也行(微信2501902696)

相關文章
相關標籤/搜索