提交 9271df88 authored 作者: 王鹏飞's avatar 王鹏飞

init

上级
node_modules
.DS_Store
dist
dist-ssr
*.local
\ No newline at end of file
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA9MjUExxOj6tfMUaU+t/k0+VokVkh1GVZACLPdxR2VcjjOkaI
qloY4TK4/uybncLhoqu9ggyiJFNmXVLxe2TxReGXhR8tAc0RTCuaFv0oHJ7HXI48
CZ/zc8sgjyd7XsuyRurKwpHWXfy9FMHE7r/9R+IUHAkIPmZ17qlwqphlePK8I1fn
DU/LOvglXPIlR55TUe6NKVoCPZXQEHHPZClH0qdnXFiUq5I1f6GMUoGCbV5DLECb
OAndCP/snqakw8oeLmoBGSig/FGrc/41l2DJxyIxm/CfaEhfnSN4hvOTAFXcro9c
gyy88H1BfT/bEhM7OO+RRaKUrV5CieeIOEmvGQIDAQABAoIBAGmkcsJ8qPsgPskJ
aSqMjjlU/Lgd+5eq1apVW6xMzHVhaY+w+TJsB+jI90Yt30tK3A5UiEkkIqYCyF7m
eQmEGwzJu5bcSZRJaHmzJ6FcSH9xlyC+0fJlcbA7riWaKIhU6O/qTO+D+Tw+42ud
5NwVR75KN9uRmlkz5xnFTraRZtm3MJmA7dwXK3hrN+dFJR2vLO3KBAtpgtpPdkK1
ObpJQ1Q7jsnEmODVRZ7n1CKZEDmXd8GBPA/jCVqgiEbVVCdkhHkyxyIMQenBReyy
tJIPf7CdL3O3PPsThhMa1P2CP/xehS4bcQSLw9wtNTJcvVPHTvffHKOKUfhUxkHu
0cpl+zECgYEA/jzySW/br7W+xS2e4VBHzY+UZJwxd/3mY3d/kasMV1zuipr6WOhQ
FVsd5uJXPRr+rHBypwyOIlP205V2K5oQEK0yT+tF+IBvKGdJv89wskCgrXcD3Kfb
dCFbt014pHw89A8jb8LBbGOPH6jhZhGkxP33CJdVPtncUc4m0hj4HHcCgYEA9nsc
KcCZOIYRlZmJ93DoukhjxaouGFDTOZoujaqasrfXUaWRnpZYekDZWa1NneOzLBEz
h1RwPcmeYLCVRmXtpRzLOKXfJY0gGSJr979I0AVkzj8A9NZcU/HxUP0GqpwBbzAp
EEShQVhjYppQ62KAwZ1tbsVWX2V1SBsa3McExO8CgYEA6kVy5aTDhOgugDeHnguB
/rN9hDBBjVZTQ/jLfolld+NUlDg21FJN6T/rD+Qli1MitfdwTupM1ukUGugw2gC/
KP7Py8D62wBObaav2KXoLPlMlkuDLYMnv501jHVA5CDvcd25Q7Ts01nyerP97zX2
5Oc5CZuZm67ZTDBwqU0E5AUCgYBIC2wL+DPRBb8WDy74mJQt/wLKwBeBG/7hk2OQ
HRHis0HIp7CMvj1WXqYpRDKvt+KjOtPo9pFoPgqBEJxRW3G/FU+BW1qCS2HadulA
HTVXOHxinJ/W8OFD2DBFD/Bm5fq1WUpnaugHhaJnK9wDMWOZND7MZfn9IFbLoMCV
T8bhGQKBgG7qsZhI9ldAqooZQ1xSua/2SBc8GI8d03g7y8kZkkx/XclbEz6X6wUu
U3PVL+neY8Qw3JxC1cHS++KIdHR2ZSoTpF00A4QvDJL0+eo1KgI88vRV8QaWLxPB
ahvXwmkKW2+jgvCAqFtepZx/KsKpQW+x3GOJyhl2tIT8sZwRmE6u
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIIFhzCCBG+gAwIBAgIQCzEi4VmynSzbyBV1UEXGojANBgkqhkiG9w0BAQsFADBu
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMS0wKwYDVQQDEyRFbmNyeXB0aW9uIEV2ZXJ5d2hlcmUg
RFYgVExTIENBIC0gRzEwHhcNMjAxMTA5MDAwMDAwWhcNMjExMTA5MjM1OTU5WjAa
MRgwFgYDVQQDEw9kZXYuZXppamluZy5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IB
DwAwggEKAoIBAQD0yNQTHE6Pq18xRpT63+TT5WiRWSHUZVkAIs93FHZVyOM6Roiq
WhjhMrj+7JudwuGiq72CDKIkU2ZdUvF7ZPFF4ZeFHy0BzRFMK5oW/SgcnsdcjjwJ
n/NzyyCPJ3tey7JG6srCkdZd/L0UwcTuv/1H4hQcCQg+ZnXuqXCqmGV48rwjV+cN
T8s6+CVc8iVHnlNR7o0pWgI9ldAQcc9kKUfSp2dcWJSrkjV/oYxSgYJtXkMsQJs4
Cd0I/+yepqTDyh4uagEZKKD8Uatz/jWXYMnHIjGb8J9oSF+dI3iG85MAVdyuj1yD
LLzwfUF9P9sSEzs475FFopStXkKJ54g4Sa8ZAgMBAAGjggJzMIICbzAfBgNVHSME
GDAWgBRVdE+yck/1YLpQ0dfmUVyaAYca1zAdBgNVHQ4EFgQUkRHkmubxZAvEWtCY
IBT9sw/3Yb8wGgYDVR0RBBMwEYIPZGV2LmV6aWppbmcuY29tMA4GA1UdDwEB/wQE
AwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwTAYDVR0gBEUwQzA3
BglghkgBhv1sAQIwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQu
Y29tL0NQUzAIBgZngQwBAgEwgYAGCCsGAQUFBwEBBHQwcjAkBggrBgEFBQcwAYYY
aHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEoGCCsGAQUFBzAChj5odHRwOi8vY2Fj
ZXJ0cy5kaWdpY2VydC5jb20vRW5jcnlwdGlvbkV2ZXJ5d2hlcmVEVlRMU0NBLUcx
LmNydDAJBgNVHRMEAjAAMIIBBAYKKwYBBAHWeQIEAgSB9QSB8gDwAHYA9lyUL9F3
MCIUVBgIMJRWjuNNExkzv98MLyALzE7xZOMAAAF1qpa6jQAABAMARzBFAiAwHOcp
Ua1H0WK4OZUHiQ1rndqnYxPHhP9XWunwpRMoagIhAOB2MPSW9M4qj6Yih7eQkydl
lgawpoBZzRzhisU+TN67AHYAXNxDkv7mq0VEsV6a1FbmEDf71fpH3KFzlLJe5vbH
DsoAAAF1qpa63gAABAMARzBFAiEA92ZeW0PgyWW3j+3wypLS0O/wI63C+x0WTvMZ
Vngp6AMCIBoThjaKif+XY11YbaV89ndqs1nDlzbEfBrFftoB9fchMA0GCSqGSIb3
DQEBCwUAA4IBAQA2geo9wQAd+vx+lwAafVRxCBQyBiS0qT413ewYpZYDnSkLX0l1
5kRdxDGWQhPzOio0ckj/jOtOlbbSsiovBBVTyYPB8WfkNjMd0psMNx2e6Wy/WKkQ
X3DqEOB4XGg0RwpebiAmz6lWxyFwIAbCrwCntkkaIF4LnIvczn6pvPFBtK2nXJJC
HL0Igbxo+xJLt3Hql7TcwkFDXz/LIB8AwhhkkhhwW45r3Eyjw8eOyzvflDPwSNH+
ByadQ+AH4H4vYYVo0ILNIPCdaokLQ+u4FttB9VQ+iGmpJ56Yg2muxWh8Qckca+vH
40RbC5aK1RSy2RIRpC5fwvq2JuV/CksP5G5Q
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEqjCCA5KgAwIBAgIQAnmsRYvBskWr+YBTzSybsTANBgkqhkiG9w0BAQsFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
QTAeFw0xNzExMjcxMjQ2MTBaFw0yNzExMjcxMjQ2MTBaMG4xCzAJBgNVBAYTAlVT
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
b20xLTArBgNVBAMTJEVuY3J5cHRpb24gRXZlcnl3aGVyZSBEViBUTFMgQ0EgLSBH
MTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALPeP6wkab41dyQh6mKc
oHqt3jRIxW5MDvf9QyiOR7VfFwK656es0UFiIb74N9pRntzF1UgYzDGu3ppZVMdo
lbxhm6dWS9OK/lFehKNT0OYI9aqk6F+U7cA6jxSC+iDBPXwdF4rs3KRyp3aQn6pj
pp1yr7IB6Y4zv72Ee/PlZ/6rK6InC6WpK0nPVOYR7n9iDuPe1E4IxUMBH/T33+3h
yuH3dvfgiWUOUkjdpMbyxX+XNle5uEIiyBsi4IvbcTCh8ruifCIi5mDXkZrnMT8n
wfYCV6v6kDdXkbgGRLKsR4pucbJtbKqIkUGxuZI2t7pfewKRc5nWecvDBZf3+p1M
pA8CAwEAAaOCAU8wggFLMB0GA1UdDgQWBBRVdE+yck/1YLpQ0dfmUVyaAYca1zAf
BgNVHSMEGDAWgBQD3lA1VtFMu2bwo+IbG8OXsj3RVTAOBgNVHQ8BAf8EBAMCAYYw
HQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBIGA1UdEwEB/wQIMAYBAf8C
AQAwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdp
Y2VydC5jb20wQgYDVR0fBDswOTA3oDWgM4YxaHR0cDovL2NybDMuZGlnaWNlcnQu
Y29tL0RpZ2lDZXJ0R2xvYmFsUm9vdENBLmNybDBMBgNVHSAERTBDMDcGCWCGSAGG
/WwBAjAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BT
MAgGBmeBDAECATANBgkqhkiG9w0BAQsFAAOCAQEAK3Gp6/aGq7aBZsxf/oQ+TD/B
SwW3AU4ETK+GQf2kFzYZkby5SFrHdPomunx2HBzViUchGoofGgg7gHW0W3MlQAXW
M0r5LUvStcr82QDWYNPaUy4taCQmyaJ+VB+6wxHstSigOlSNF2a6vg4rgexixeiV
4YSB03Yqp2t3TeZHM9ESfkus74nQyW7pRGezj+TC44xCagCQQOzzNmzEAP2SnCrJ
sNE2DpRVMnL8J6xBRdjmOsC3N6cQuKuRXbzByVBjCqAA8t1L0I+9wXJerLPyErjy
rMKWaBFLmfK/AHNF4ZihwPGOc7w6UHczBZXH5RFzJNnww+WnKuTPI0HfnVH8lg==
-----END CERTIFICATE-----
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>web-pay-sdk</title>
<link rel="stylesheet" href="../dist/style.css" />
</head>
<body>
<input type="button" value="立即购买" onclick="buy()" />
<script src="../dist/web-pay-sdk.umd.js"></script>
<script>
function buy() {
ZJPay.buy({
params: {
shop_id: '6811126345599287296',
spu_id: '6811127527038255104',
sku_id: '6811127527067615232',
redirect_url: ''
}
})
}
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
差异被折叠。
{
"name": "web-pay-sdk",
"version": "0.0.0",
"files": [
"dist"
],
"main": "./dist/web-pay-sdk.umd.js",
"module": "./dist/web-pay-sdk.es.js",
"scripts": {
"dev": "vite",
"build": "vite build",
"serve": "vite preview"
},
"dependencies": {
"axios": "^0.21.1",
"mitt": "^2.1.0",
"qrcode.vue": "^3.2.2",
"query-string": "^7.0.0",
"vant": "^3.1.0-beta.0",
"vue": "^3.0.5"
},
"devDependencies": {
"@vitejs/plugin-vue": "^1.2.3",
"@vue/compiler-sfc": "^3.0.5",
"vite": "^2.3.7",
"vite-plugin-style-import": "^1.0.0"
}
}
<template>
<!-- 支付方式选择 -->
<van-dialog
v-model:show="payMethodVisible"
title="支付方式"
confirm-button-text="去支付"
show-cancel-button
@confirm="pay"
>
<div class="pay-method">
<!-- 扫码支付方式 -->
<van-radio-group v-model="params.payment_method" v-if="isQrPay">
<van-radio name="1">微信支付</van-radio>
<van-radio name="11">支付宝支付</van-radio>
</van-radio-group>
<!-- 跳转第三方支付 -->
<van-radio-group v-model="params.payment_method" v-else>
<van-radio name="4">微信支付</van-radio>
<van-radio name="12">支付宝支付</van-radio>
</van-radio-group>
</div>
</van-dialog>
<!-- 支付二维码 -->
<van-dialog
v-model:show="qrPayVisible"
:title="qrPayTitle"
confirm-button-text="支付完成"
show-cancel-button
@confirm="payCallback"
>
<div class="qr-pay">
<qrcode-vue :value="order.payment_url" :size="240" />
</div>
</van-dialog>
</template>
<script>
import QrcodeVue from 'qrcode.vue'
import queryString from 'query-string'
import { getOpenId, wxJSPay } from '@/utils/wxPay'
import * as api from '@/api'
export default {
components: { QrcodeVue },
data() {
const UA = navigator.userAgent
return {
isMobile: /iphone/i.test(UA) || (/android/i.test(UA) && /mobile/i.test(UA)),
isWechat: /micromessenger/i.test(UA),
isAliPay: /alipayclient/i.test(UA),
payMethodVisible: false, // 支付方式
qrPayVisible: false, // 扫码支付
params: { buy_count: '1', payment_method: '' }, // 订单参数
order: {}, // 创建订单返回的数据
buyOptions: {} // 外部出入的数据
}
},
computed: {
isQrPay() {
return !this.isMobile
},
qrPayTitle() {
return this.params.payment_method === '1' ? '微信扫码支付' : '支付宝扫码支付'
},
query() {
return queryString.parse(location.search, { parseBooleans: true })
}
},
methods: {
// 立即购买
buy(options) {
this.buyOptions = options
localStorage.setItem('buy', JSON.stringify(options))
Object.assign(this.params, options.params)
if (this.isMobile && (this.isWechat || this.isAliPay)) {
this.pay()
} else {
this.showPayMethod()
}
},
// 显示支付方式选择
showPayMethod() {
this.params.payment_method = this.isQrPay ? '1' : '4'
this.payMethodVisible = true
},
// 去支付
pay() {
this.createOrder(this.params).then(order => {
this.order = order
if (this.isQrPay) {
this.qrPayVisible = true
} else if (this.isWechat) {
wxJSPay(order, this.payCallback)
} else {
location.href = order.payment_url
}
})
},
// 支付回调
async payCallback() {
const { callback } = this.buyOptions
const order = await this.getOrder()
callback && callback(order)
},
// 创建订单
createOrder(options) {
let defaultParams = {}
// 微信
if (this.isWechat) {
const openId = localStorage.getItem('openId')
if (!openId) {
getOpenId(this.query.code, this.pay)
return Promise.reject('openId不存在')
}
defaultParams = { open_id: openId, payment_method: '3' }
}
// 支付宝
if (this.isAliPay) {
defaultParams = { payment_method: '12' }
}
const params = Object.assign(options, defaultParams)
return api.createOrder(params).then(resp => resp.data)
},
// 获取订单
getOrder() {
return api.getOrderList({ order_detail_id: this.order.order_detail_id }).then(resp => {
const [first = {}] = resp.data.data
return first
})
}
},
mounted() {
this.$mitt.on('buy', this.buy)
if (this.query.is_pay) {
try {
const buyOptions = JSON.parse(localStorage.getItem('buy'))
this.buy(buyOptions)
} catch (error) {
console.log(error)
}
}
}
}
</script>
<style>
.pay-method {
padding: 20px;
}
.pay-method .van-radio {
margin: 20px;
}
.qr-pay {
padding: 30px;
text-align: center;
}
</style>
\ No newline at end of file
import httpRequest from '@/utils/axios'
/**
* 创建订单
* */
export function createOrder(data) {
return httpRequest.post('/api/shop/order/add', data)
}
/**
* 获取订单
* */
export function getOrderList(data) {
return httpRequest.post('/api/shop/order/search', data)
}
/**
* 获取用户OpenId
* */
export function getOpenId(data) {
return httpRequest.post('/api/usercenter/v1/wechat/get-openid', data, {
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
})
}
import { createApp } from 'vue'
import App from './App.vue'
import { Dialog, RadioGroup, Radio } from 'vant'
import mitt from 'mitt'
const app = createApp(App)
app.use(Dialog)
app.use(Radio)
app.use(RadioGroup)
app.config.globalProperties.$mitt = mitt()
const root = document.createElement('div')
root.setAttribute('id', 'zj-pay')
document.body.appendChild(root)
app.mount('#zj-pay')
export default {
buy(options) {
app.config.globalProperties.$mitt.emit('buy', options)
}
}
import axios from 'axios'
import queryString from 'query-string'
const httpRequest = axios.create({
baseURL: 'https://shop.ezijing.com',
timeout: 60000,
withCredentials: true,
headers: { 'Content-Type': 'application/json' }
})
// 请求拦截
httpRequest.interceptors.request.use(
function (config) {
if (config.headers['Content-Type'] === 'application/x-www-form-urlencoded') {
config.data = queryString.stringify(config.data)
}
if (config.headers['Content-Type'] === 'multipart/form-data') {
const formData = new window.FormData()
for (const key in config.data) {
formData.append(key, config.data[key])
}
config.data = formData
}
return config
},
function (error) {
return Promise.reject(error)
}
)
export default httpRequest
import * as api from '@/api'
/**
* 获取微信openId
* */
export function getCode() {
const href = location.href.includes('?') ? `${location.href}&is_pay=true` : `${location.href}?is_pay=true`
const redirectURI = `https://pages.ezijing.com/given/auth.html?redirect_uri=${encodeURIComponent(href)}`
location.href = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx451c01d40d090d7a&redirect_uri=${redirectURI}&response_type=code&scope=snsapi_base`
}
/**
* 获取微信openId
* */
export function getOpenId(code, callback) {
if (!code) {
return getCode()
}
api.getOpenId({ code, identity: 'ezijing' }).then(resp => {
const openId = resp.data.openid
openId && localStorage.setItem('openId', openId)
callback && callback(openId)
})
}
/**
* 微信JSAPI支付
* */
export function wxJSPay(order, callback) {
if (!order.payment_more_info) {
alert('订单创建错误')
return
}
const payInfo = JSON.parse(order.payment_more_info)
WeixinJSBridge.invoke('getBrandWCPayRequest', payInfo, resp => {
callback && callback(resp)
})
}
const fs = require('fs')
const path = require('path')
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import styleImport from 'vite-plugin-style-import'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
styleImport({
libs: [
{
libraryName: 'vant',
esModule: true,
resolveStyle: name => `vant/es/${name}/style`
}
]
})
],
server: {
host: 'dev.ezijing.com',
https: {
key: fs.readFileSync(path.join(__dirname, './cert/dev.ezijing.com.key')),
cert: fs.readFileSync(path.join(__dirname, './cert/dev.ezijing.com.pem'))
}
},
build: {
lib: {
entry: path.resolve(__dirname, 'src/main.js'),
name: 'ZJPay'
}
},
resolve: {
alias: [{ find: '@', replacement: '/src' }]
}
})
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论