佣金
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
18631081161 2026-03-30 15:29:56 +08:00
parent 2dd04e11e4
commit 58b34666bd
13 changed files with 140 additions and 39 deletions

View File

@ -124,6 +124,22 @@
</el-form> </el-form>
</el-tab-pane> </el-tab-pane>
<!-- 最低佣金 -->
<el-tab-pane label="最低佣金" name="min_commission">
<el-form label-width="120px" style="max-width: 500px;">
<el-form-item label="最低佣金">
<el-input-number v-model="minCommission" :min="0.01" :max="100" :step="0.1" :precision="2" />
<span style="margin-left: 8px; color: #909399;"></span>
</el-form-item>
<el-form-item>
<span style="color: #909399; font-size: 13px;">小程序下单页的跑腿佣金最低金额修改后提示文字自动更新</span>
</el-form-item>
<el-form-item>
<el-button type="primary" :loading="saving" @click="saveMinCommission">保存</el-button>
</el-form-item>
</el-form>
</el-tab-pane>
<!-- 冻结时间 --> <!-- 冻结时间 -->
<el-tab-pane label="冻结时间" name="freeze_days"> <el-tab-pane label="冻结时间" name="freeze_days">
<el-form label-width="120px" style="max-width: 500px;"> <el-form label-width="120px" style="max-width: 500px;">
@ -184,6 +200,7 @@ const commissionRules = ref([])
// //
const configs = reactive({ qrcode: '', agreement: '', privacy: '', runner_agreement: '', withdrawal_guide: '' }) const configs = reactive({ qrcode: '', agreement: '', privacy: '', runner_agreement: '', withdrawal_guide: '' })
const freezeDays = ref(1) const freezeDays = ref(1)
const minCommission = ref(1.0)
// //
const pageBannerList = [ const pageBannerList = [
@ -257,6 +274,23 @@ async function saveFreezeDays() {
} }
} }
async function fetchMinCommission() {
try {
const res = await request.get('/admin/config/min_commission')
if (res?.value) minCommission.value = parseFloat(res.value) || 1.0
} catch (e) {}
}
async function saveMinCommission() {
saving.value = true
try {
await request.put('/admin/config/min_commission', { value: String(minCommission.value) })
ElMessage.success('最低佣金保存成功')
} finally {
saving.value = false
}
}
async function fetchPageBanners() { async function fetchPageBanners() {
for (const item of pageBannerList) { for (const item of pageBannerList) {
try { try {
@ -287,6 +321,7 @@ onMounted(async () => {
fetchConfig('runner_agreement'), fetchConfig('runner_agreement'),
fetchConfig('withdrawal_guide'), fetchConfig('withdrawal_guide'),
fetchFreezeDays(), fetchFreezeDays(),
fetchMinCommission(),
fetchPageBanners() fetchPageBanners()
]) ])
}) })

View File

@ -1,5 +1,5 @@
{ {
"name" : "miniapp", "name" : "校园跑腿侠",
"appid" : "__UNI__F1854F8", "appid" : "__UNI__F1854F8",
"description" : "", "description" : "",
"versionName" : "1.0.0", "versionName" : "1.0.0",

View File

@ -63,7 +63,7 @@
<view class="form-group"> <view class="form-group">
<text class="form-label">6.跑腿佣金</text> <text class="form-label">6.跑腿佣金</text>
<view class="input-box"> <view class="input-box">
<input v-model="form.commission" type="digit" placeholder="请输入跑腿佣金最低1.0元" placeholder-class="placeholder" /> <input v-model="form.commission" type="digit" :placeholder="`请输入跑腿佣金,最低${minCommission}元`" placeholder-class="placeholder" />
</view> </view>
<text class="form-tip">佣金先由平台保管接单方完成订单后才会收到佣金</text> <text class="form-tip">佣金先由平台保管接单方完成订单后才会收到佣金</text>
</view> </view>
@ -79,7 +79,7 @@
</template> </template>
<script> <script>
import { createOrder, getPageBanner } from '../../utils/api' import { createOrder, getPageBanner, getMinCommission } from '../../utils/api'
export default { export default {
data() { data() {
@ -94,13 +94,15 @@ export default {
phone: '', phone: '',
commission: '' commission: ''
}, },
submitting: false submitting: false,
minCommission: 1.0
} }
}, },
onLoad() { onLoad() {
const sysInfo = uni.getSystemInfoSync() const sysInfo = uni.getSystemInfoSync()
this.statusBarHeight = sysInfo.statusBarHeight || 0 this.statusBarHeight = sysInfo.statusBarHeight || 0
this.loadBanner() this.loadBanner()
this.loadMinCommission()
this.restoreFormData() this.restoreFormData()
}, },
methods: { methods: {
@ -122,14 +124,20 @@ export default {
if (res?.value) this.bannerUrl = res.value if (res?.value) this.bannerUrl = res.value
} catch (e) {} } catch (e) {}
}, },
async loadMinCommission() {
try {
const res = await getMinCommission()
if (res?.value) this.minCommission = parseFloat(res.value) || 1.0
} catch (e) {}
},
validateCommission() { validateCommission() {
const val = this.form.commission const val = this.form.commission
if (!val) { if (!val) {
uni.showToast({ title: '请输入跑腿佣金', icon: 'none' }); return false uni.showToast({ title: '请输入跑腿佣金', icon: 'none' }); return false
} }
const num = parseFloat(val) const num = parseFloat(val)
if (isNaN(num) || num < 1.0) { if (isNaN(num) || num < this.minCommission) {
uni.showToast({ title: '跑腿佣金不可低于1.0元', icon: 'none' }); return false uni.showToast({ title: `跑腿佣金不可低于${this.minCommission}`, icon: 'none' }); return false
} }
if (val.includes('.') && val.split('.')[1].length > 1) { if (val.includes('.') && val.split('.')[1].length > 1) {
uni.showToast({ title: '佣金最多支持小数点后1位', icon: 'none' }); return false uni.showToast({ title: '佣金最多支持小数点后1位', icon: 'none' }); return false

View File

@ -54,7 +54,7 @@
<text class="form-label">跑腿佣金</text> <text class="form-label">跑腿佣金</text>
<view class="commission-input"> <view class="commission-input">
<text class="commission-unit">¥</text> <text class="commission-unit">¥</text>
<input class="form-input commission-field" v-model="form.commission" type="digit" placeholder="最低1.0元" /> <input class="form-input commission-field" v-model="form.commission" type="digit" :placeholder="`最低${minCommission}元`" />
</view> </view>
</view> </view>
</view> </view>
@ -68,7 +68,7 @@
</template> </template>
<script> <script>
import { createOrder } from '../../utils/api' import { createOrder, getMinCommission } from '../../utils/api'
import { useCartStore } from '../../stores/cart' import { useCartStore } from '../../stores/cart'
export default { export default {
@ -81,7 +81,8 @@ export default {
commission: '' commission: ''
}, },
submitting: false, submitting: false,
statusBarHeight: 0 statusBarHeight: 0,
minCommission: 1.0
} }
}, },
computed: { computed: {
@ -105,6 +106,7 @@ export default {
onLoad() { onLoad() {
const sysInfo = uni.getSystemInfoSync() const sysInfo = uni.getSystemInfoSync()
this.statusBarHeight = sysInfo.statusBarHeight || 0 this.statusBarHeight = sysInfo.statusBarHeight || 0
this.loadMinCommission()
// //
if (this.cartStore.totalCount === 0) { if (this.cartStore.totalCount === 0) {
uni.showToast({ title: '购物车为空', icon: 'none' }) uni.showToast({ title: '购物车为空', icon: 'none' })
@ -113,6 +115,12 @@ export default {
}, },
methods: { methods: {
goBack() { uni.navigateBack() }, goBack() { uni.navigateBack() },
async loadMinCommission() {
try {
const res = await getMinCommission()
if (res?.value) this.minCommission = parseFloat(res.value) || 1.0
} catch (e) {}
},
/** 校验佣金 */ /** 校验佣金 */
validateCommission() { validateCommission() {
const val = this.form.commission const val = this.form.commission
@ -121,8 +129,8 @@ export default {
return false return false
} }
const num = parseFloat(val) const num = parseFloat(val)
if (isNaN(num) || num < 1.0) { if (isNaN(num) || num < this.minCommission) {
uni.showToast({ title: '跑腿佣金不可低于1.0元', icon: 'none' }) uni.showToast({ title: `跑腿佣金不可低于${this.minCommission}`, icon: 'none' })
return false return false
} }
if (val.includes('.') && val.split('.')[1].length > 1) { if (val.includes('.') && val.split('.')[1].length > 1) {

View File

@ -1,4 +1,4 @@
<template> <template>
<view class="order-page"> <view class="order-page">
<!-- 自定义导航栏 --> <!-- 自定义导航栏 -->
<view class="custom-navbar" :style="{ paddingTop: statusBarHeight + 'px' }"> <view class="custom-navbar" :style="{ paddingTop: statusBarHeight + 'px' }">
@ -50,7 +50,7 @@
<view class="form-group"> <view class="form-group">
<text class="form-label">4.跑腿佣金</text> <text class="form-label">4.跑腿佣金</text>
<view class="input-box"> <view class="input-box">
<input v-model="form.commission" type="digit" placeholder="请输入跑腿佣金" <input v-model="form.commission" type="digit" :placeholder="`请输入跑腿佣金,最低${minCommission}元`"
placeholder-class="placeholder" /> placeholder-class="placeholder" />
</view> </view>
<text class="form-tip">佣金先由平台保管接单方完成订单后才会收到佣金</text> <text class="form-tip">佣金先由平台保管接单方完成订单后才会收到佣金</text>
@ -70,7 +70,8 @@
<script> <script>
import { import {
createOrder, createOrder,
getPageBanner getPageBanner,
getMinCommission
} from '../../utils/api' } from '../../utils/api'
export default { export default {
@ -84,7 +85,8 @@
}, },
submitting: false, submitting: false,
statusBarHeight: 0, statusBarHeight: 0,
bannerUrl: '' bannerUrl: '',
minCommission: 1.0
} }
}, },
computed: { computed: {
@ -99,6 +101,7 @@
const sysInfo = uni.getSystemInfoSync() const sysInfo = uni.getSystemInfoSync()
this.statusBarHeight = sysInfo.statusBarHeight || 0 this.statusBarHeight = sysInfo.statusBarHeight || 0
this.loadBanner() this.loadBanner()
this.loadMinCommission()
this.restoreFormData() this.restoreFormData()
}, },
methods: { methods: {
@ -122,6 +125,12 @@
if (res?.value) this.bannerUrl = res.value if (res?.value) this.bannerUrl = res.value
} catch (e) {} } catch (e) {}
}, },
async loadMinCommission() {
try {
const res = await getMinCommission()
if (res?.value) this.minCommission = parseFloat(res.value) || 1.0
} catch (e) {}
},
/** 校验佣金 */ /** 校验佣金 */
validateCommission() { validateCommission() {
const val = this.form.commission const val = this.form.commission
@ -133,9 +142,9 @@
return false return false
} }
const num = parseFloat(val) const num = parseFloat(val)
if (isNaN(num) || num < 1.0) { if (isNaN(num) || num < this.minCommission) {
uni.showToast({ uni.showToast({
title: '跑腿佣金不可低于1.0元', title: `跑腿佣金不可低于${this.minCommission}`,
icon: 'none' icon: 'none'
}) })
return false return false

View File

@ -63,7 +63,7 @@
<view class="form-group"> <view class="form-group">
<text class="form-label">6.跑腿佣金</text> <text class="form-label">6.跑腿佣金</text>
<view class="input-box"> <view class="input-box">
<input v-model="form.commission" type="digit" placeholder="请输入跑腿佣金最低1.0元" placeholder-class="placeholder" /> <input v-model="form.commission" type="digit" :placeholder="`请输入跑腿佣金,最低${minCommission}元`" placeholder-class="placeholder" />
</view> </view>
<text class="form-tip">佣金先由平台保管接单方完成订单后才会收到佣金</text> <text class="form-tip">佣金先由平台保管接单方完成订单后才会收到佣金</text>
</view> </view>
@ -79,7 +79,7 @@
</template> </template>
<script> <script>
import { createOrder, getPageBanner } from '../../utils/api' import { createOrder, getPageBanner, getMinCommission } from '../../utils/api'
export default { export default {
data() { data() {
@ -94,13 +94,15 @@ export default {
phone: '', phone: '',
commission: '' commission: ''
}, },
submitting: false submitting: false,
minCommission: 1.0
} }
}, },
onLoad() { onLoad() {
const sysInfo = uni.getSystemInfoSync() const sysInfo = uni.getSystemInfoSync()
this.statusBarHeight = sysInfo.statusBarHeight || 0 this.statusBarHeight = sysInfo.statusBarHeight || 0
this.loadBanner() this.loadBanner()
this.loadMinCommission()
this.restoreFormData() this.restoreFormData()
}, },
methods: { methods: {
@ -122,6 +124,12 @@ export default {
if (res?.value) this.bannerUrl = res.value if (res?.value) this.bannerUrl = res.value
} catch (e) {} } catch (e) {}
}, },
async loadMinCommission() {
try {
const res = await getMinCommission()
if (res?.value) this.minCommission = parseFloat(res.value) || 1.0
} catch (e) {}
},
validateCommission() { validateCommission() {
const val = this.form.commission const val = this.form.commission
if (!val) { if (!val) {
@ -129,8 +137,8 @@ export default {
return false return false
} }
const num = parseFloat(val) const num = parseFloat(val)
if (isNaN(num) || num < 1.0) { if (isNaN(num) || num < this.minCommission) {
uni.showToast({ title: '跑腿佣金不可低于1.0元', icon: 'none' }) uni.showToast({ title: `跑腿佣金不可低于${this.minCommission}`, icon: 'none' })
return false return false
} }
if (val.includes('.') && val.split('.')[1].length > 1) { if (val.includes('.') && val.split('.')[1].length > 1) {

View File

@ -62,7 +62,7 @@
<view class="form-group"> <view class="form-group">
<text class="form-label">7.跑腿佣金</text> <text class="form-label">7.跑腿佣金</text>
<view class="input-box"> <view class="input-box">
<input v-model="form.commission" type="digit" placeholder="请输入跑腿佣金最低1.0元" <input v-model="form.commission" type="digit" :placeholder="`请输入跑腿佣金,最低${minCommission}元`"
placeholder-class="placeholder" /> placeholder-class="placeholder" />
</view> </view>
<text class="form-tip">佣金先由平台保管接单方完成订单后才会收到佣金</text> <text class="form-tip">佣金先由平台保管接单方完成订单后才会收到佣金</text>
@ -82,7 +82,8 @@
<script> <script>
import { import {
createOrder, createOrder,
getPageBanner getPageBanner,
getMinCommission
} from '../../utils/api' } from '../../utils/api'
export default { export default {
@ -99,7 +100,8 @@
}, },
submitting: false, submitting: false,
statusBarHeight: 0, statusBarHeight: 0,
bannerUrl: '' bannerUrl: '',
minCommission: 1.0
} }
}, },
computed: { computed: {
@ -114,6 +116,7 @@
const sysInfo = uni.getSystemInfoSync() const sysInfo = uni.getSystemInfoSync()
this.statusBarHeight = sysInfo.statusBarHeight || 0 this.statusBarHeight = sysInfo.statusBarHeight || 0
this.loadBanner() this.loadBanner()
this.loadMinCommission()
this.restoreFormData() this.restoreFormData()
}, },
methods: { methods: {
@ -137,6 +140,12 @@
if (res?.value) this.bannerUrl = res.value if (res?.value) this.bannerUrl = res.value
} catch (e) {} } catch (e) {}
}, },
async loadMinCommission() {
try {
const res = await getMinCommission()
if (res?.value) this.minCommission = parseFloat(res.value) || 1.0
} catch (e) {}
},
validateCommission() { validateCommission() {
const val = this.form.commission const val = this.form.commission
if (!val) { if (!val) {
@ -147,9 +156,9 @@
return false return false
} }
const num = parseFloat(val) const num = parseFloat(val)
if (isNaN(num) || num < 1.0) { if (isNaN(num) || num < this.minCommission) {
uni.showToast({ uni.showToast({
title: '跑腿佣金不可低于1.0元', title: `跑腿佣金不可低于${this.minCommission}`,
icon: 'none' icon: 'none'
}); });
return false return false

View File

@ -217,6 +217,11 @@ export function getPageBanner(page) {
return request({ url: `/api/config/page-banner/${page}` }) return request({ url: `/api/config/page-banner/${page}` })
} }
/** 获取最低佣金配置 */
export function getMinCommission() {
return request({ url: '/api/config/min-commission' })
}
// ==================== 腾讯 IM ==================== // ==================== 腾讯 IM ====================
/** 获取 IM UserSig */ /** 获取 IM UserSig */

View File

@ -6,8 +6,8 @@
*/ */
// API 基础地址,按环境切换 // API 基础地址,按环境切换
// const BASE_URL = 'http://localhost:5099' const BASE_URL = 'http://localhost:5099'
const BASE_URL = 'http://api.zwz.shhmkjgs.cn' // const BASE_URL = 'http://api.zwz.shhmkjgs.cn'
/** /**
* 获取本地存储的 token * 获取本地存储的 token

View File

@ -82,6 +82,18 @@ public static class ConfigEndpoints
}); });
}); });
// 获取最低佣金配置
app.MapGet("/api/config/min-commission", async (AppDbContext db) =>
{
var config = await db.SystemConfigs.FirstOrDefaultAsync(c => c.Key == "min_commission");
return Results.Ok(new ConfigResponse
{
Key = "min_commission",
Value = config?.Value ?? "1.0",
UpdatedAt = config?.UpdatedAt ?? DateTime.MinValue
});
});
// 管理端获取指定配置 // 管理端获取指定配置
app.MapGet("/api/admin/config/{key}", async (string key, AppDbContext db) => app.MapGet("/api/admin/config/{key}", async (string key, AppDbContext db) =>
{ {
@ -101,6 +113,7 @@ public static class ConfigEndpoints
var allowedKeys = new HashSet<string> var allowedKeys = new HashSet<string>
{ {
"qrcode", "agreement", "privacy", "runner_agreement", "withdrawal_guide", "freeze_days", "qrcode", "agreement", "privacy", "runner_agreement", "withdrawal_guide", "freeze_days",
"min_commission",
"page_banner_pickup", "page_banner_delivery", "page_banner_help", "page_banner_purchase", "page_banner_food", "page_banner_pickup", "page_banner_delivery", "page_banner_help", "page_banner_purchase", "page_banner_food",
"page_banner_order-hall" "page_banner_order-hall"
}; };

View File

@ -25,10 +25,15 @@ public static class OrderEndpoints
return Results.BadRequest(new { code = 400, message = "订单类型不合法" }); return Results.BadRequest(new { code = 400, message = "订单类型不合法" });
} }
// 佣金校验:最低 1.0 元 // 佣金校验:读取最低佣金配置
if (request.Commission < 1.0m) var minCommissionConfig = await db.SystemConfigs.FirstOrDefaultAsync(c => c.Key == "min_commission");
var minCommission = 1.0m;
if (minCommissionConfig != null && decimal.TryParse(minCommissionConfig.Value, out var configMin))
minCommission = configMin;
if (request.Commission < minCommission)
{ {
return Results.BadRequest(new { code = 400, message = "跑腿佣金不可低于1.0元" }); return Results.BadRequest(new { code = 400, message = $"跑腿佣金不可低于{minCommission}元" });
} }
// 佣金校验:小数点后最多 1 位 // 佣金校验:小数点后最多 1 位

View File

@ -12,7 +12,7 @@ public class WxPayService
private readonly string _appId; private readonly string _appId;
private readonly string _mchId; private readonly string _mchId;
private readonly string _apiV3Key; private readonly string _apiV3Key;
private readonly string _publicKeyId; private readonly string _serialNo;
private readonly RSA _privateKey; private readonly RSA _privateKey;
private readonly HttpClient _httpClient; private readonly HttpClient _httpClient;
@ -21,7 +21,7 @@ public class WxPayService
_appId = config["WeChat:AppId"]!; _appId = config["WeChat:AppId"]!;
_mchId = config["WeChat:MchId"]!; _mchId = config["WeChat:MchId"]!;
_apiV3Key = config["WeChat:MchApiV3Key"]!; _apiV3Key = config["WeChat:MchApiV3Key"]!;
_publicKeyId = config["WeChat:MchPublicKeyId"]!; _serialNo = config["WeChat:MchSerialNo"]!;
_httpClient = httpClient; _httpClient = httpClient;
// 加载商户私钥 // 加载商户私钥
@ -61,8 +61,9 @@ public class WxPayService
var timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString(); var timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString();
var nonce = Guid.NewGuid().ToString("N"); var nonce = Guid.NewGuid().ToString("N");
var signature = Sign("POST", url, timestamp, nonce, json); var signature = Sign("POST", url, timestamp, nonce, json);
request.Headers.Add("Authorization", $"WECHATPAY2-SHA256-RSA2048 mchid=\"{_mchId}\",nonce_str=\"{nonce}\",timestamp=\"{timestamp}\",serial_no=\"{_publicKeyId}\",signature=\"{signature}\""); request.Headers.Add("Authorization", $"WECHATPAY2-SHA256-RSA2048 mchid=\"{_mchId}\",nonce_str=\"{nonce}\",timestamp=\"{timestamp}\",serial_no=\"{_serialNo}\",signature=\"{signature}\"");
request.Headers.Add("Accept", "application/json"); request.Headers.Add("Accept", "application/json");
request.Headers.Add("User-Agent", "CampusErrand/1.0");
var response = await _httpClient.SendAsync(request); var response = await _httpClient.SendAsync(request);
var responseBody = await response.Content.ReadAsStringAsync(); var responseBody = await response.Content.ReadAsStringAsync();
@ -157,8 +158,9 @@ public class WxPayService
var timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString(); var timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString();
var nonce = Guid.NewGuid().ToString("N"); var nonce = Guid.NewGuid().ToString("N");
var signature = Sign("POST", url, timestamp, nonce, json); var signature = Sign("POST", url, timestamp, nonce, json);
request.Headers.Add("Authorization", $"WECHATPAY2-SHA256-RSA2048 mchid=\"{_mchId}\",nonce_str=\"{nonce}\",timestamp=\"{timestamp}\",serial_no=\"{_publicKeyId}\",signature=\"{signature}\""); request.Headers.Add("Authorization", $"WECHATPAY2-SHA256-RSA2048 mchid=\"{_mchId}\",nonce_str=\"{nonce}\",timestamp=\"{timestamp}\",serial_no=\"{_serialNo}\",signature=\"{signature}\"");
request.Headers.Add("Accept", "application/json"); request.Headers.Add("Accept", "application/json");
request.Headers.Add("User-Agent", "CampusErrand/1.0");
var response = await _httpClient.SendAsync(request); var response = await _httpClient.SendAsync(request);
var responseBody = await response.Content.ReadAsStringAsync(); var responseBody = await response.Content.ReadAsStringAsync();

View File

@ -23,9 +23,8 @@
"AppSecret": "2b3b9d15fee1ed3e6204d67c86facfaf", "AppSecret": "2b3b9d15fee1ed3e6204d67c86facfaf",
"MchId": "1742482400", "MchId": "1742482400",
"MchApiV3Key": "1djcnfLHDJi3944HDLJK3015698fD1Oy", "MchApiV3Key": "1djcnfLHDJi3944HDLJK3015698fD1Oy",
"MchPublicKeyId": "PUB_KEY_ID_0117424824002026032900211571000202", "MchSerialNo": "6D9B2C7B3B12CD03D76090EB946F1B6F2FA8051C",
"MchPrivateKeyPem": "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQD3NZeEFc7UGujMK54+Z2xj0oJT/ykvIILqpCQ5M3DI4whuVu4C9LJwLWiRi5NTid8irx0p6kxgPw958e/szLnjmKJsURJWKWlz7VRcj4H1a888Xdam0kVFmWmdYjrIISl/NZfiKEys80KVGrBN/pIu3UZIQ9rvFaAiRK5ARTA5KINrXGnjQKMF7jgWZoVmc+nJhvh68Wo8H3ys8SzOMaTSinjlmcdCIgUzDJJp7tVIj6uCWR2JSouJyVE0nZRa5GHLujlj8sX2zLvpRm8txu3ksgFbVF/hPxAcRQ0qHjyowzKsHmJDUU9/Ms4yeLqzaM9cDuEYTPcWkmkDdD2DeDi1AgMBAAECggEBAMgv1t24hz/N9rz3iXLBb826N53roB8wtbNrboX/uRKEf1xS+vTb0O/0ZZyPKaPZnx9ILVa3DFhYWKEIoaDh/JppDQan9DBf4qxlAQ7fi38BadVZrCx1VHFTFWrElBNif2crMC6NMeJQL5fs/955C0n2GCcHA/DeU0nM0krrfGybYal93ufr2OranRSoDAYWxNks/VG7RzBJdj5kxe8pdLFDU7l1d52V5C4whBEjZMpp5JoEBsYTEbQ/pcU5i4LhE1OPVNRRHteMNgCSVICZr5xmtSNRy0XkAUTm+5Z3P+iP8IWIdkcrrlKFaZOjQTn21xCWhYeSmTWMkTQ8PfgrlsECgYEA//tkpck73ZcQQQBf7OOj1lFGFKN0KdiONYMrsXLQ5yud3jfWAUQ0PEqEa+4HadwK/S+lq0g3IXRQ1SuLyZSTYOAPVohIv9bVxh7oAoBZbMluLEE9E38AtcTMS3FiigMac+X8z3bJWIA0IJSvWD5JTHxJ/VZeUShdEQAKwY3lAtECgYEA9zoKc4M8Jfx5ga4X15SffKk4S+t51PY5lbuT/507/o+8imjMiuaoIGGjRd0vylOrACS/QriAnqusyvxpF9nYSLWDYMJPloKfxf+BYvQB8tv088afHzw2Q0K2yFyZzfW/i+uBZc4UaPrRmtUgEU/NNWreOmfbr+j7BDiotTNQ6KUCgYABlfcbp9F9H/Bz1qLBfu+G5l3+xrxzfenznupoYQO2SujhdYsX2upP7U5AtOrK1xgiVWc7VmkxBd1yVKC7EPaQxRKTQKjit1v/rDVXvp/PMrhCAe1073Z7qcpyNTOdE0PYr/YO+vdoWvL3uLQVYd1mYea7cQuIiS16a3ulk1F14QKBgQCYWVoLaPnt5rHx6hijLuFBbv5UOp3vUHSYAunnATvxWR40pPQ3PICqw8Bb0zwaEIk2I28BbLVGEkD/LaCNpB8WX1TAkb194K0Y1KUlF30D7ev7NZDlLLO7qyb8PaRCOYh6bvxkgiQttTLpmSCTynuIyXx8vXex5X6aUVgVobPgSQKBgAnOA6G1UeJKjIARPNXEyOLu+8N3+bWVonhNQfMrTN9Aa5YCrkYkQPIzbHMzlPCL/uiK91yk+wvgAohvpQysQe54KkqZxK5ucjUGwqNRGMAkmlS+669wKEcx5tYzek00sQzQVBFWDJeH/xtJEbw30bTPuSDtBhMV3OgwiuJeuRm5", "MchPrivateKeyPem": "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQD3NZeEFc7UGujMK54+Z2xj0oJT/ykvIILqpCQ5M3DI4whuVu4C9LJwLWiRi5NTid8irx0p6kxgPw958e/szLnjmKJsURJWKWlz7VRcj4H1a888Xdam0kVFmWmdYjrIISl/NZfiKEys80KVGrBN/pIu3UZIQ9rvFaAiRK5ARTA5KINrXGnjQKMF7jgWZoVmc+nJhvh68Wo8H3ys8SzOMaTSinjlmcdCIgUzDJJp7tVIj6uCWR2JSouJyVE0nZRa5GHLujlj8sX2zLvpRm8txu3ksgFbVF/hPxAcRQ0qHjyowzKsHmJDUU9/Ms4yeLqzaM9cDuEYTPcWkmkDdD2DeDi1AgMBAAECggEBAMgv1t24hz/N9rz3iXLBb826N53roB8wtbNrboX/uRKEf1xS+vTb0O/0ZZyPKaPZnx9ILVa3DFhYWKEIoaDh/JppDQan9DBf4qxlAQ7fi38BadVZrCx1VHFTFWrElBNif2crMC6NMeJQL5fs/955C0n2GCcHA/DeU0nM0krrfGybYal93ufr2OranRSoDAYWxNks/VG7RzBJdj5kxe8pdLFDU7l1d52V5C4whBEjZMpp5JoEBsYTEbQ/pcU5i4LhE1OPVNRRHteMNgCSVICZr5xmtSNRy0XkAUTm+5Z3P+iP8IWIdkcrrlKFaZOjQTn21xCWhYeSmTWMkTQ8PfgrlsECgYEA//tkpck73ZcQQQBf7OOj1lFGFKN0KdiONYMrsXLQ5yud3jfWAUQ0PEqEa+4HadwK/S+lq0g3IXRQ1SuLyZSTYOAPVohIv9bVxh7oAoBZbMluLEE9E38AtcTMS3FiigMac+X8z3bJWIA0IJSvWD5JTHxJ/VZeUShdEQAKwY3lAtECgYEA9zoKc4M8Jfx5ga4X15SffKk4S+t51PY5lbuT/507/o+8imjMiuaoIGGjRd0vylOrACS/QriAnqusyvxpF9nYSLWDYMJPloKfxf+BYvQB8tv088afHzw2Q0K2yFyZzfW/i+uBZc4UaPrRmtUgEU/NNWreOmfbr+j7BDiotTNQ6KUCgYABlfcbp9F9H/Bz1qLBfu+G5l3+xrxzfenznupoYQO2SujhdYsX2upP7U5AtOrK1xgiVWc7VmkxBd1yVKC7EPaQxRKTQKjit1v/rDVXvp/PMrhCAe1073Z7qcpyNTOdE0PYr/YO+vdoWvL3uLQVYd1mYea7cQuIiS16a3ulk1F14QKBgQCYWVoLaPnt5rHx6hijLuFBbv5UOp3vUHSYAunnATvxWR40pPQ3PICqw8Bb0zwaEIk2I28BbLVGEkD/LaCNpB8WX1TAkb194K0Y1KUlF30D7ev7NZDlLLO7qyb8PaRCOYh6bvxkgiQttTLpmSCTynuIyXx8vXex5X6aUVgVobPgSQKBgAnOA6G1UeJKjIARPNXEyOLu+8N3+bWVonhNQfMrTN9Aa5YCrkYkQPIzbHMzlPCL/uiK91yk+wvgAohvpQysQe54KkqZxK5ucjUGwqNRGMAkmlS+669wKEcx5tYzek00sQzQVBFWDJeH/xtJEbw30bTPuSDtBhMV3OgwiuJeuRm5"
"WxPublicKeyPem": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2GJl9vHz0Yi62pgtXR1iS5sc7QLAANag82qGHlN83AJynP84wSpwBduvzR8Vh/FDFQTg6CTGbtWPsSpj+yTbfkz3YukigL+6JZ3tXeK+HKnDdamK0GD5p9xe6Msm1eLccfD+dThTQIlFW0gsvTEFUXsZw6SyEodLY7RuVKEb1Tkb5dmUB4UbZaQblTlrWLp7fDKHDxsDKICFR/qFCjbI1D9qug6DD1qv4M7teATMmnHXolTPrGwpXKRJOgLRYZrq0j7hdMY/p/L9JwsDK+ioPcskcBW5iAfdUTL5NeVJ30sBHs7KQdtr0Zk6Fj/aGcUpt7+8rAIIK//6pmHwWCN0rQIDAQAB"
}, },
"Upload": { "Upload": {
"MaxFileSizeBytes": 5242880, "MaxFileSizeBytes": 5242880,