欢迎光临
我们一直在努力

微信小程序从0到1接入微信支付的完整攻略

本文面向有微信小程序开发经验的开发者,系统梳理微信支付从申请到上线的全流程,提供可直接使用的代码示例。

一、微信支付接入前置条件

1.1 资质要求

接入微信支付,你的小程序主体需要满足以下条件:

项目要求
小程序主体 企业主体(个体工商户仅限部分类目)
小程序状态 已发布上线
营业执照 在有效期内
对公账户 用于结算(个体户可用法人对私账户)
法人身份证 正反面照片

个人开发者无法直接接入微信支付,但可以通过第三方服务商(如微信支付服务商平台)间接受理。

1.2 商户号申请流程

  • 登录 微信支付商户平台,点击"成为商家"
  • 填写营业执照信息、法人信息、结算账户
  • 等待审核(通常1-3个工作日)
  • 审核通过后,通过邮箱查收商户号(mch_id)和API密钥设置链接
  • 登录商户平台,设置 APIv3 密钥,下载微信支付平台证书
  • 关键配置项:

    • mch_id:商户号
    • appid:小程序的 AppID
    • APIv3 密钥:用于回调通知解密、敏感信息加解密
    • API 证书序列号:标识你的商户证书
    • 商户API私钥:签名使用,务必妥善保管

    1.3 绑定小程序与商户号

    在商户平台 → 产品中心 → AppID账号管理 中,关联你的小程序 AppID。这一步确保支付时能正确校验调用方身份。

    二、完整接入流程

    整体流程如下:

    code复制

    用户点击支付 → 小程序请求后端下单 → 后端调用统一下单API → 微信返回prepay_id
    → 后端签名返回支付参数 → 小程序调用wx.requestPayment → 用户完成支付
    → 微信异步回调后端 → 后端验签更新订单状态

    2.1 配置支付域名

    在商户平台 → 产品中心 → 开发配置 中,添加你的后端域名(仅 HTTPS)。同时在小程序管理后台 → 开发管理 → 开发设置中,配置 request合法域名 包含你的后端域名。

    2.2 前端调起支付的参数

    后端需要返回以下参数给前端:

    javascript复制

    {
    timeStamp: '1490840669',
    nonceStr: '5K8264ILTKCH16CQ2502SI8ZNMTM67VS',
    package: 'prepay_id=wx20170306425458994c08807f1909503344',
    signType: 'RSA',
    paySign: 'oR9d8PuhnIc+YZlz…' // RSA签名
    }

    三、前端实现

    3.1 完整的支付调用代码

    javascript复制

    // pages/order/confirm.js
    const app = getApp()

    Page({
    data: {
    orderInfo: null,
    paying: false
    },

    // 发起支付
    async handlePay() {
    if (this.data.paying) return
    this.setData({ paying: true })

    try {
    // 1. 先在本地创建订单(或后端创建)
    const orderId = await this.createOrder()

    // 2. 请求后端获取支付参数
    const payParams = await this.getPayParams(orderId)

    // 3. 调起微信支付
    await this.wxPay(payParams)

    // 4. 支付成功,跳转结果页
    wx.redirectTo({
    url: `/pages/pay/result?orderId=${orderId}&status=success`
    })
    } catch (err) {
    console.error('支付流程异常:', err)

    // 根据错误类型做不同处理
    if (err.errMsg && err.errMsg.includes('cancel')) {
    // 用户取消支付
    wx.redirectTo({
    url: `/pages/pay/result?status=cancel&orderId=${orderId}`
    })
    } else if (err.code === 'ORDER_EXPIRED') {
    wx.showModal({
    title: '订单已过期',
    content: '当前订单已超过支付时效,请重新下单',
    showCancel: false
    })
    } else {
    wx.showToast({
    title: '支付失败,请重试',
    icon: 'none'
    })
    }
    } finally {
    this.setData({ paying: false })
    }
    },

    // 调起wx.requestPayment
    wxPay(payParams) {
    return new Promise((resolve, reject) => {
    wx.requestPayment({
    timeStamp: payParams.timeStamp,
    nonceStr: payParams.nonceStr,
    package: payParams.package,
    signType: payParams.signType,
    paySign: payParams.paySign,

    success(res) {
    // 注意:success只代表用户完成了支付动作
    // 真正的支付结果以后端回调为准
    console.log('支付动作完成:', res)
    resolve(res)
    },

    fail(err) {
    console.error('支付失败:', err)
    reject(err)
    },

    // 支付状态查询(用户离开微信后的兜底)
    complete() {
    // 可在此处做轮询查单
    }
    })
    })
    },

    // 请求后端获取支付参数
    async getPayParams(orderId) {
    const res = await wx.request({
    url: `${app.globalData.apiBase}/pay/create`,
    method: 'POST',
    data: { orderId },
    header: {
    'Authorization': `Bearer ${wx.getStorageSync('token')}`
    }
    })

    if (res.statusCode !== 200 || !res.data.success) {
    throw new Error(res.data.message || '获取支付参数失败')
    }
    return res.data.data
    },

    // 创建订单
    async createOrder() {
    const res = await wx.request({
    url: `${app.globalData.apiBase}/order/create`,
    method: 'POST',
    data: {
    items: this.data.orderInfo.items,
    addressId: this.data.orderInfo.addressId,
    remark: this.data.remark
    }
    })
    return res.data.data.orderId
    }
    })

    3.2 支付结果页设计

    javascript复制

    // pages/pay/result.js
    Page({
    onLoad(options) {
    const { status, orderId } = options
    this.setData({ status, orderId })

    // 如果是success状态,向后端确认真实支付结果
    if (status === 'success') {
    this.verifyPayResult(orderId)
    }
    },

    // 轮询确认支付结果(防止回调延迟)
    verifyPayResult(orderId) {
    let count = 0
    const maxRetry = 6
    const timer = setInterval(async () => {
    count++
    try {
    const res = await wx.request({
    url: `${getApp().globalData.apiBase}/order/${orderId}/pay-status`
    })
    if (res.data.data.paid) {
    clearInterval(timer)
    this.setData({ status: 'success', verified: true })
    } else if (count >= maxRetry) {
    clearInterval(timer)
    this.setData({ status: 'pending' })
    }
    } catch (e) {
    if (count >= maxRetry) clearInterval(timer)
    }
    }, 2000)
    },

    // 重新支付
    retryPay() {
    wx.redirectTo({
    url: `/pages/order/confirm?orderId=${this.data.orderId}`
    })
    },

    // 查看订单详情
    viewOrder() {
    wx.redirectTo({
    url: `/pages/order/detail?orderId=${this.data.orderId}`
    })
    },

    // 回到首页
    backHome() {
    wx.switchTab({ url: '/pages/index/index' })
    }
    })

    结果页 WXML:

    xml复制

    <!– pages/pay/result.wxml –>
    <view class="result-page">
    <!– 成功 –>
    <block wx:if="{{status === 'success'}}">
    <view class="status-icon success-icon">✓</view>
    <view class="status-title">支付成功</view>
    <view class="status-desc" wx:if="{{verified}}">订单已确认,商家正在处理</view>
    <view class="status-desc" wx:else>支付结果确认中…</view>
    <view class="btn-group">
    <button class="btn-primary" bindtap="viewOrder">查看订单</button>
    <button class="btn-secondary" bindtap="backHome">回到首页</button>
    </view>
    </block>

    <!– 取消 –>
    <block wx:elif="{{status === 'cancel'}}">
    <view class="status-icon cancel-icon">!</view>
    <view class="status-title">支付已取消</view>
    <view class="status-desc">订单尚未支付,可随时重新支付</view>
    <view class="btn-group">
    <button class="btn-primary" bindtap="retryPay">重新支付</button>
    <button class="btn-secondary" bindtap="viewOrder">查看订单</button>
    </view>
    </block>

    <!– 失败 –>
    <block wx:elif="{{status === 'fail'}}">
    <view class="status-icon fail-icon">✕</view>
    <view class="status-title">支付失败</view>
    <view class="status-desc">{{errorMsg || '请检查网络后重试'}}</view>
    <view class="btn-group">
    <button class="btn-primary" bindtap="retryPay">重新支付</button>
    <button class="btn-secondary" bindtap="backHome">回到首页</button>
    </view>
    </block>

    <!– 待确认 –>
    <block wx:elif="{{status === 'pending'}}">
    <view class="status-icon pending-icon">⏳</view>
    <view class="status-title">支付结果确认中</view>
    <view class="status-desc">支付结果正在确认,请稍后在订单详情页查看</view>
    <view class="btn-group">
    <button class="btn-primary" bindtap="viewOrder">查看订单</button>
    <button class="btn-secondary" bindtap="backHome">回到首页</button>
    </view>
    </block>
    </view>

    四、后端实现(Node.js)

    4.1 项目依赖

    bash复制

    npm install @wechatpay/node-v3-utils axios crypto-js

    4.2 支付配置模块

    javascript复制

    // config/pay.js
    const fs = require('fs')
    const path = require('path')

    module.exports = {
    appId: process.env.WX_APPID,
    mchId: process.env.WX_MCH_ID,
    apiKey: process.env.WX_API_KEY, // APIv2密钥(兼容用)
    apiV3Key: process.env.WX_API_V3_KEY, // APIv3密钥
    serialNo: process.env.WX_SERIAL_NO, // 商户证书序列号
    privateKey: fs.readFileSync(
    path.join(__dirname, '../certs/apiclient_key.pem'), 'utf8'
    ),
    notifyUrl: `${process.env.API_BASE}/pay/notify`,
    // 微信支付API基础URL
    baseUrl: 'https://api.mch.weixin.qq.com'
    }

    4.3 统一下单接口

    javascript复制

    // services/payService.js
    const axios = require('axios')
    const crypto = require('crypto')
    const payConfig = require('../config/pay')
    const { createSign, getAuthorization } = require('../utils/wxSign')

    class PayService {
    /**
    * JSAPI下单(小程序支付)
    * @param {Object} params
    * @param {string} params.orderId 商户订单号
    * @param {number} params.amount 金额(元)
    * @param {string} params.description 商品描述
    * @param {string} params.openid 用户openid
    * @returns {Object} 支付参数(给前端调wx.requestPayment)
    */
    async createOrder({ orderId, amount, description, openid }) {
    // 1. 金额转分(微信支付单位为分)
    const total = Math.round(amount * 100)

    // 2. 生成商户订单号唯一标识
    const outTradeNo = `MINI_${orderId}_${Date.now()}`

    // 3. 构造请求体
    const body = {
    appid: payConfig.appId,
    mchid: payConfig.mchId,
    description: description.substring(0, 127),
    out_trade_no: outTradeNo,
    notify_url: payConfig.notifyUrl,
    amount: {
    total,
    currency: 'CNY'
    },
    payer: {
    openid
    }
    }

    // 4. 调用统一下单API
    const url = `${payConfig.baseUrl}/v3/pay/transactions/jsapi`
    const authorization = getAuthorization('POST', url, body)

    const res = await axios.post(url, body, {
    headers: {
    'Authorization': authorization,
    'Content-Type': 'application/json',
    'Accept': 'application/json'
    },
    timeout: 10000
    })

    const { prepay_id } = res.data

    // 5. 生成前端支付参数并签名
    const payParams = this.buildClientPayParams(prepay_id)

    // 6. 保存预支付记录
    await this.savePrepayRecord(outTradeNo, orderId, total, prepay_id)

    return {
    …payParams,
    outTradeNo
    }
    }

    /**
    * 构造前端wx.requestPayment所需参数
    */
    buildClientPayParams(prepayId) {
    const timeStamp = Math.floor(Date.now() / 1000).toString()
    const nonceStr = crypto.randomBytes(16).toString('hex')

    // 构造签名串:appid\\n时间戳\\n随机串\\nprepay_id\\n
    const message = [
    payConfig.appId,
    timeStamp,
    nonceStr,
    prepayId
    ].join('\\n')

    // RSA签名
    const sign = crypto.createSign('RSA-SHA256')
    sign.update(message)
    const paySign = sign.sign(payConfig.privateKey, 'base64')

    return {
    appId: payConfig.appId,
    timeStamp,
    nonceStr,
    package: `prepay_id=${prepayId}`,
    signType: 'RSA',
    paySign
    }
    }

    /**
    * 保存预支付记录(防重复下单)
    */
    async savePrepayRecord(outTradeNo, orderId, total, prepayId) {
    // 写入数据库或Redis
    // 防止同一订单重复下单
    }

    /**
    * 查询订单状态
    */
    async queryOrder(outTradeNo) {
    const url = `${payConfig.baseUrl}/v3/pay/transactions/out-trade-no/${outTradeNo}?mchid=${payConfig.mchId}`
    const authorization = getAuthorization('GET', url, '')

    const res = await axios.get(url, {
    headers: { 'Authorization': authorization }
    })

    return {
    tradeState: res.data.trade_state,
    tradeStateDesc: res.data.trade_state_desc,
    paid: res.data.trade_state === 'SUCCESS',
    transactionId: res.data.transaction_id,
    payerOpenid: res.data.payer?.openid,
    paidTime: res.data.success_time
    }
    }
    }

    module.exports = new PayService()

    4.4 签名工具

    javascript复制

    // utils/wxSign.js
    const crypto = require('crypto')
    const payConfig = require('../config/pay')

    /**
    * 生成请求签名头
    * HTTP方法\\n请求URL\\n请求体时间戳\\n随机串\\n
    */
    function getAuthorization(method, url, body) {
    const timeStamp = Math.floor(Date.now() / 1000).toString()
    const nonceStr = crypto.randomBytes(16).toString('hex')

    const bodyStr = body ? JSON.stringify(body) : ''

    // 构造签名串
    const signMessage = [
    method,
    new URL(url).pathname,
    timeStamp,
    nonceStr,
    bodyStr
    ].join('\\n')

    // RSA-SHA256签名
    const sign = crypto.createSign('RSA-SHA256')
    sign.update(signMessage)
    const signature = sign.sign(payConfig.privateKey, 'base64')

    // 构造Authorization头
    const authStr = [
    `WECHATPAY2-SHA256-RSA2048`,
    `mchid="${payConfig.mchId}"`,
    `nonce_str="${nonceStr}"`,
    `timestamp="${timeStamp}"`,
    `serial_no="${payConfig.serialNo}"`,
    `signature="${signature}"`
    ].join(', ')

    return authStr
    }

    /**
    * 验证回调通知签名
    */
    function verifyNotifySign(headers, body, timestamp, nonce, signature) {
    const { 'wechatpay-timestamp': ts, 'wechatpay-nonce': n, 'wechatpay-serial': serial, 'wechatpay-signature': sig } = headers

    // 构造验签串
    const message = `${ts}\\n${n}\\n${body}\\n`

    // 使用微信平台公钥验签(需提前下载)
    const verify = crypto.createVerify('RSA-SHA256')
    verify.update(message)
    return verify.verify(wechatPayPublicKey, sig, 'base64')
    }

    module.exports = { getAuthorization, verifyNotifySign }

    4.5 回调通知处理

    javascript复制

    // controllers/payController.js
    const express = require('express')
    const crypto = require('crypto')
    const payConfig = require('../config/pay')

    const router = express.Router()

    /**
    * 支付结果回调通知
    * 微信会以POST方式通知该接口,重复通知直到返回200
    */
    router.post('/notify', async (req, res) => {
    try {
    // 1. 验证签名(防止伪造回调)
    const isValid = verifyNotifySign(req)
    if (!isValid) {
    console.error('回调签名验证失败')
    return res.status(401).json({ code: 'FAIL', message: '签名验证失败' })
    }

    // 2. 解密通知内容(AES-256-GCM)
    const { resource } = req.body
    const {
    ciphertext,
    associated_data,
    nonce
    } = resource

    const decrypted = decryptAES256GCM(
    ciphertext,
    associated_data,
    nonce,
    payConfig.apiV3Key
    )

    const orderData = JSON.parse(decrypted)

    // 3. 处理不同交易状态
    switch (orderData.trade_state) {
    case 'SUCCESS':
    await handlePaySuccess(orderData)
    break
    case 'NOTPAY':
    console.log('订单未支付:', orderData.out_trade_no)
    break
    case 'CLOSED':
    await handlePayClosed(orderData)
    break
    case 'REFUND':
    await handlePayRefund(orderData)
    break
    default:
    console.warn('未知交易状态:', orderData.trade_state)
    }

    // 4. 返回成功响应(重要!不返回200微信会重复通知)
    res.json({ code: 'SUCCESS', message: '成功' })

    } catch (err) {
    console.error('支付回调处理异常:', err)
    // 返回失败让微信重试
    res.status(500).json({ code: 'FAIL', message: err.message })
    }
    })

    /**
    * AES-256-GCM解密
    */
    function decryptAES256GCM(ciphertext, associatedData, nonce, apiKey) {
    const decipher = crypto.createDecipheriv(
    'aes-256-gcm',
    Buffer.from(apiKey, 'utf8'),
    Buffer.from(nonce, 'utf8')
    )

    decipher.setAAD(Buffer.from(associatedData, 'utf8'))
    const ciphertextBuf = Buffer.from(ciphertext, 'base64')

    // GCM模式:密文末尾16字节为auth tag
    const authTag = ciphertextBuf.subarray(ciphertextBuf.length – 16)
    const encryptedData = ciphertextBuf.subarray(0, ciphertextBuf.length – 16)
    decipher.setAuthTag(authTag)

    const decrypted = Buffer.concat([
    decipher.update(encryptedData),
    decipher.final()
    ])

    return decrypted.toString('utf8')
    }

    /**
    * 处理支付成功逻辑
    */
    async function handlePaySuccess(orderData) {
    const { out_trade_no, transaction_id, payer, success_time, amount } = orderData

    // 幂等性检查:防止重复处理同一笔回调
    const processed = await checkCallbackProcessed(transaction_id)
    if (processed) {
    console.log('回调已处理过:', transaction_id)
    return
    }

    // 更新订单状态
    await updateOrderStatus(out_trade_no, {
    paid: true,
    transactionId: transaction_id,
    payerOpenid: payer.openid,
    paidTime: success_time,
    paidAmount: amount.total
    })

    // 标记回调已处理
    await markCallbackProcessed(transaction_id)

    // 触发业务逻辑:发货通知、库存扣减等
    await triggerAfterPayHooks(out_trade_no)
    }

    module.exports = router

    五、支付安全

    5.1 防重复支付中间件

    javascript复制

    // middleware/payGuard.js

    /**
    * 防重复支付中间件
    * 同一订单在短时间内只能发起一次支付
    */
    function preventDuplicatePay(redisClient) {
    return async (req, res, next) => {
    const { orderId } = req.body
    const userId = req.user.id

    const lockKey = `pay_lock:${userId}:${orderId}`

    // 尝试获取分布式锁(5分钟过期)
    const acquired = await redisClient.set(lockKey, '1', {
    NX: true,
    EX: 300
    })

    if (!acquired) {
    return res.status(429).json({
    success: false,
    message: '支付请求处理中,请勿重复提交'
    })
    }

    res.locals.payLockKey = lockKey
    next()
    }
    }

    /**
    * 防金额篡改校验
    * 下单时记录金额,回调时比对
    */
    async function verifyPayAmount(outTradeNo, actualTotal) {
    const order = await getOrder(outTradeNo)
    if (!order) throw new Error('订单不存在')

    // 订单已支付
    if (order.paid) throw new Error('订单已支付')

    // 金额比对
    const expectedTotal = Math.round(order.amount * 100)
    if (expectedTotal !== actualTotal) {
    console.error(`金额不一致: 预期${expectedTotal} 实际${actualTotal}`)
    throw new Error('支付金额与订单金额不一致')
    }
    }

    /**
    * 防回调伪造
    * 验证微信回调的签名 + IP白名单
    */
    function validateCallbackSource(req) {
    // 1. 验证签名
    const signatureValid = verifyNotifySign(req)
    if (!signatureValid) return false

    // 2. IP白名单(微信回调IP段)
    const clientIp = req.ip
    const wechatPayIpRanges = [
    '101.226.', '101.227.', // 上海
    '180.163.', // 上海
    '140.207.', // 上海
    '203.205.', '203.205.147.' // 广州
    ]
    return wechatPayIpRanges.some(range => clientIp.startsWith(range))
    }

    module.exports = { preventDuplicatePay, verifyPayAmount, validateCallbackSource }

    5.2 安全配置清单

    javascript复制

    // 安全检查清单
    const SECURITY_CHECKLIST = {
    // 1. 密钥安全
    'API密钥不硬编码': '使用环境变量或密钥管理服务',
    '私钥文件权限': '仅应用服务可读 (chmod 400)',
    'APIv3密钥强度': '至少32位随机字符串',

    // 2. 签名验证
    '回调签名验证': '必须验签,不验签=裸奔',
    '请求签名': '所有API请求均需签名',
    '时间戳校验': '请求时间戳5分钟内有效',

    // 3. 业务安全
    '订单金额校验': '回调时比对原始订单金额',
    '幂等处理': '同一笔回调不重复处理',
    '分布式锁': '防止并发重复下单',

    // 4. 数据安全
    '敏感信息脱敏': '日志中不打印完整密钥/手机号',
    'HTTPS强制': '回调URL必须HTTPS',
    '数据库加密': '支付敏感字段加密存储'
    }

    六、常见问题排查

    6.1 签名错误

    症状:return_code=FAIL, return_msg=签名错误

    排查步骤:

  • 确认签名类型:V3接口使用 RSA-SHA256,不是 MD5
  • 检查签名串格式:字段之间用\\n分隔,不要有空格
  • 确认商户证书序列号与密钥匹配
  • 检查请求体是否与签名时使用的完全一致(JSON序列化顺序可能不同)
  • javascript复制

    // 调试工具:打印签名串用于对比
    function debugSign(method, url, body) {
    const bodyStr = body ? JSON.stringify(body) : ''
    console.log('签名原文:')
    console.log([method, new URL(url).pathname, '时间戳', '随机串', bodyStr].join('\\n'))
    }

    6.2 订单过期

    症状:trade_state=NOTPAY 或前端报 ORDER_EXPIRED

    解决方案:

    • 微信预支付订单默认2小时过期,可通过 time_expire 参数自定义(最长24小时)
    • 建议在前端显示倒计时,过期前引导用户重新下单
    • 过期订单不需要手动关闭,微信会自动关闭

    6.3 回调未收到

    排查清单:

    code复制

    □ 回调URL是否配置正确(商户平台→开发配置→回调地址)
    □ 服务器是否能被公网访问
    □ HTTPS证书是否有效
    □ 是否正确返回了 { code: 'SUCCESS' } 响应体
    □ 检查服务器防火墙和安全组规则
    □ 查看微信商户平台→交易中心→订单查询中的通知状态

    6.4 支付金额不一致

    根本原因:前端传给后端的金额与实际支付金额存在精度问题。

    javascript复制

    // ✅ 正确:使用整数分计算
    const totalFen = Math.round(parseFloat(amountYuan) * 100)

    // ❌ 错误:浮点数直接计算
    const totalFen = amountYuan * 100 // 0.1 * 100 = 10.000000000000002

    强制规范:所有金额计算在服务端完成,前端仅传递数量和商品ID,后端查库计算金额。

    七、微信支付新能力(2025+)

    7.1 免密支付(委托代扣)

    适用于周期性扣费场景(如会员续费、打车预扣费):

    javascript复制

    // 签约流程
    // 1. 前端引导用户签署代扣协议
    wx.navigateToMiniProgram({
    appId: 'wx1234567890abcdef', // 微信支付签约小程序
    path: 'pages/contract/index',
    extraData: {
    mch_id: '商户号',
    plan_id: '签约计划ID',
    contract_code: '合约号'
    }
    })

    // 2. 后端调用委托代扣API扣费
    // POST /v3/pay/transactions/papay/apply

    7.2 微信先享卡

    一种"先享后付"的营销工具,用户承诺达标后享受优惠,未达标自动扣费:

    code复制

    接入流程:商户平台→产品中心→先享卡→申请→配置规则
    用户路径:小程序内展示先享卡→用户领取→达标享优惠/未达标扣费

    7.3 分账功能

    适合平台型小程序(如外卖、分销):

    javascript复制

    // 统一下单时指定分账规则
    const body = {
    // …其他参数
    settle_info: {
    profit_sharing: true
    }
    }

    // 支付成功后调用分账API
    // POST /v3/profitsharing/transactions

    八、总结

    微信支付接入的核心要点:

  • 资质先行:企业主体、商户号、API密钥缺一不可
  • 安全为本:签名验证、金额校验、幂等处理是底线
  • 回调可靠:异步回调是确认支付的唯一标准,前端结果仅供参考
  • 错误兜底:轮询查单作为回调的补充手段
  • 日志完整:全链路记录请求/响应,问题排查时事半功倍
  • 完整代码示例可在官方文档 微信支付开发者文档 中找到更多细节,建议与本文对照阅读。

    赞(0)
    未经允许不得转载:171主机测评 » 微信小程序从0到1接入微信支付的完整攻略
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址