提交 592b0a90 authored 作者: huangxingyao's avatar huangxingyao

init project

上级
流水线 #231 已失败 于阶段
#################
## Eclipse
#################
*.pydevproject
.project
.metadata
bin/
tmp/
*.mp4
*.tmp
*.bak
*.swp
*~.nib
local.properties
.classpath
.settings/
.loadpath
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# CDT-specific
.cproject
# PDT-specific
.buildpath
#################
## Visual Studio
#################
## Ignore Visual Studio temporary files, build result, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates
# Build result
[Dd]ebug/
[Rr]elease/
*_i.c
*_p.c
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.vspscc
.builds
*.dotCover
## TODO: If you have NuGet Package Restore enabled, uncomment this
#packages/
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
# Visual Studio profiler
*.psess
*.vsp
# ReSharper is a .NET coding add-in
_ReSharper*
# Installshield output folder
[Ee]xpress
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish
# Others
[Bb]in
[Oo]bj
sql
TestResults
*.Cache
ClientBin
stylecop.*
~$*
*.dbmdl
Generated_Code #added for RIA/Silverlight projects
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
############
## Windows
############
# Windows image file caches
Thumbs.db
# Folder config file
Desktop.ini
#############
## Python
#############
*.py[co]
# Packages
*.egg
*.egg-info
eggs
parts
bin
var
sdist
develop-eggs
.installed.cfg
# Installer logs
pip-log.txt
# Unit test / coverage reports
.coverage
.tox
#Translations
*.mo
#Mr Developer
.mr.developer.cfg
# Mac crap
.DS_Store
#Project specific
/data-sources.xml
target/
/yamj3-filescanner/*.log
/yamj3-filescanner/logs/
**/nbactions.xml
**/nb-configuration.xml
**/nbproject/
#IDEA Project files
*.iml
*.rej
.idea/
.gradle/
*.log
*.log.*
*.m3u8
*.mps
*.p
*.mmr
*.session
*.class
out/
**/build/libs
**/build/resources
**/build/**/test
version.txt
/gradle.properties
# tve-member-web
## MFC Bill Main Module of MFC Member Web Suite
#### Contains:
Main Financial Module for receiving payments from User
TODO:List Interfaces
description = 'Valor Bill'
buildscript {
repositories {
maven { url "http://maven.aliyun.com/nexus/content/groups/public/" }
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
springBoot {
mainClassName = "com.valor.tve.member.bill.BillMainApplication"
}
configurations {
compile.exclude module: "spring-boot-starter-data-redis"
compile.exclude module: "spring-boot-starter-tomcat"
compile.exclude module: "checker-qual"
compile.exclude group: 'org.apache.commons', module: "commons-dbcp2"
compile.exclude group: 'net.sf.ehcache', module: "*"
compile.exclude group: 'io.shardingsphere', module: "*"
compile.exclude group: 'com.valor.common', module: "common-session"
compile.exclude group: 'org.hibernate', module: "hibernate-ehcache"
compile.exclude group: "org.jgroups", module: "jgroups"
}
dependencies {
compile project(':tve-member-api-module')
compile project(':common:tve-common')
compile group: 'com.valor.mfc', name: 'mfc-common-web', version: '0.1.0'
compile group: 'com.valor.mfc', name: 'mfc-account-api-stub', version: '0.1.0'
//METRICS
compile files("${rootProject.projectDir}/libs/els-metric-agent-0.1.0-SNAPSHOT.jar")
//COMMON
compile "org.springframework.boot:spring-boot-starter-web:$springBootVersion"
compile "org.springframework.boot:spring-boot-starter-undertow:$springBootVersion"
compile group: 'org.springframework', name: 'spring-aspects', version:"${springVersion}"
compile group: 'com.squareup.retrofit2', name: 'retrofit', version: "${retrofitVersion}"
//DB
compile group: 'org.springframework', name: 'spring-orm', version:"${springVersion}"
compile group: 'com.zaxxer', name: 'HikariCP', version: "${HikariCPVersion}"
compile group: 'org.hibernate', name: 'hibernate-core', version:"${hibernateVersion}"
runtime group: 'mysql', name: 'mysql-connector-java', version:"${mysqlCJVersion}"
compile group: 'com.mashape.unirest', name: 'unirest-java', version: '1.4.9'
compile group: 'com.squareup.retrofit2', name: 'retrofit', version: "${retrofitVersion}"
compile group: 'com.squareup.retrofit2', name: 'converter-gson', version: "${retrofitVersion}"
compile group: 'org.springframework.boot', name: 'spring-boot-starter-thymeleaf', version: "${springBootVersion}"
compile group: 'org.springframework.boot', name: 'spring-boot-starter-mail', version: "${springBootVersion}"
compile files("${rootProject.projectDir}/libs/tve-oauth-client-1.0.0.jar")
}
tve.member.bill.db.url=jdbc:mysql://127.0.0.1:3306/tve_member_db?characterEncoding=UTF-8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=Asia/Shanghai
tve.member.bill.db.username=root
tve.member.bill.db.password=142536
#tve_member_db_mexico
tve.member.bill.db.driver=com.mysql.cj.jdbc.Driver
tve.member.bill.db.dialect=org.hibernate.dialect.MySQL57InnoDBDialect
tve.member.bill.db.showSql=true
tve.member.bill.db.formatSql=false
tve.member.bill.db.hbm2ddlAuto=update
server.port=2094
#订单错误的最大执行次数
order.pending.scheduler.error.maxtime=30
#每次查询的pending状态订单的最大数量
order.pending.scheduler.error.maxNumber=100
#查询释放的锁的最大数据量
tve.member.scheduler.release.lock.maxNumber=100
#获取释放锁的时间间隔
tve.member.bill.release.lock.interval=1800000
#制卡重试错误执行最大错误执行次数
tve.member.scheduler.make.code.error.maxtime=30
#付款制卡错误的最大查询数量
tve.member.scheduler.make.code.maxNumber=100
#锁卡重试错误执行最大错误执行次数
tve.member.scheduler.revoke.code.error.maxtime=30
#退款锁卡错误的最大查询数量
tve.member.scheduler.revoke.code.maxNumber=100
#更新卡状态失败最大执行次数
tve.member.update.card.error.maxtime=5
#解锁释放时间(单位:秒)
tve.bill.invoice.lock.time=60
#释放锁定时器配置
lock.scheduler.exp=0 0/5 * * * ?
#获取消息tips的最大行数
tve.payment.orderPayment.tip.max.line=10;
#获取订单状态更新定时器
order.scheduler.pending.card.exp=0 0/5 * * * ?
order.scheduler.pending.other.exp=0 0 0/12 * * ?
order.scheduler.chargeback.exp=0/30 * * * * ?
#制卡锁卡
tve.member.scheduler.make.code.exp=0 0/30 * * * ?
tve.member.scheduler.lock.code.exp=0 0/30 * * * ?
#释放长时间处于锁定状态的锁
user.scheduler.release.lock=0 0/30 * * * ?
#商品续订信息
tve.member.renew.plan.en=(Auto-Renew)
tve.member.renew.plan.pt=(Renovação Automática)
#tve系统邮件发送人
tve.email.default.sender.name=tve.notification@tvexpress.info
#连接邮件服务器超时时间
tve.email.connectiontimeout=5000
tve.email.writetimeout=5000
tve.email.timeout=5000
#邮件服务器用户名
tve.email.default.username=postmaster@mail.tvexpress.pro
#邮件服务器密码
tve.email.default.password=a7ca85bb2a827f81455438dbf38160ad-f135b0f1-a5e89631
#邮件服务器端口号
tve.email.default.port=465
#邮件服务器地址
tve.email.default.host=smtp.mailgun.org
#发送邮件协议
tve.email.default.protocol=smtp
#邮件服务器密码
tve.email.title.en=[TVExpress] Order Detail
tve.email.title.pt=[TVExpress] Detalhe do pedido
#发送邮件时,邮件模板上显示时间的时区
tve.email.zone=GMT-3
#邮件内容
tve.member.email.tve.code.message.en=TVE Renewal Code: {%s}
tve.member.email.tve.code.message.pt=Código de recarga TVE:{%s}
tve.member.email.hot.code.message.en=HOT Account Code: {%s} Password: {%s}
tve.member.email.hot.code.message.pt=Código da conta HOT: {%s} Senha: {%s}
tve.member.email.mfc.code.message.en=MFC Account Code: {%s} Password: {%s}
tve.member.email.mfc.code.message.pt=Código da conta MFC: {%s} Senha: {%s}
tve.member.email.mfc.info.en=MFC website and APP download click http://www.myfamilycinema.com
tve.member.email.mfc.info.pt=Clique http://www.myfamilycinema.com para baixar aplicativo MFC.
tve.member.email.installments.info.en= You have chosen {%s} installments. Please, check your bank statement.
tve.member.email.installments.info.pt= Você escolheu realizar o pagamento em {%s} parcelas. Por favor, verifique seu extrato bancário.
tve.member.bill.error.9999.en=Error: Invalid Input
tve.member.bill.error.9999.pt=Erro: Formato inválido
tve.member.bill.error.9995.en=Network error
tve.member.bill.error.9995.pt=Network error
tve.member.bill.error.9997.en=system error
tve.member.bill.error.9997.pt=Erro no sistema
#payment error
tve.member.bill.error.1001.en=product not found
tve.member.bill.error.1001.pt=Produto não encontrado
tve.member.bill.error.1002.en=Order not found
tve.member.bill.error.1002.pt=Pedido não encontrado
tve.member.bill.error.1003.en=The operation is too frequent, please try again later.
tve.member.bill.error.1003.pt=A operação é muito frequente. Por favor,tente novamente mais tarde.
tve.member.bill.error.1004.en=Card not found or deleted
tve.member.bill.error.1004.pt=Cartão não encontrado ou eliminado
tve.member.bill.error.1005.en=Order status error
tve.member.bill.error.1005.pt=Erro no estado do pedido
tve.member.bill.error.1006.en=Save card exception
tve.member.bill.error.1006.pt=Exceção ao salvar o cartão
tve.member.bill.error.1007.en=Invalid payment order ID
tve.member.bill.error.1007.pt=Número ID do pagamento inválido
tve.member.bill.error.1008.en=Invalid payment gateway response
tve.member.bill.error.1008.pt=Resposta inválida da plataforma de pagamento
tve.member.bill.error.1010.en=The card is disabled
tve.member.bill.error.1010.pt=O cartão não está disponível
tve.member.bill.error.1104.en=Invalid payment - Invalid first name.
tve.member.bill.error.1104.pt=Pagamento inválido - Nome inválido.
tve.member.bill.error.1105.en=Invalid payment - Invalid last name.
tve.member.bill.error.1105.pt=Pagamento inválido - Sobrenome inválido.
tve.member.bill.error.1106.en=Invalid payment - Invalid identity card.
tve.member.bill.error.1106.pt=Pagamento inválido - Documento inválido.
tve.member.bill.error.1107.en=Invalid payment - Invalid e-mail.
tve.member.bill.error.1107.pt=Pagamento inválido - E-mail inválido.
#Get country by currency
tve.bill.payment.currency.country.brl=BR
#payment method sort
tve.bill.payment.method.sort=TICKET=1&BANK_TRANSFER=2&CARD=3&E-WALLET=4
#method type text
en.tve.bill.payment.method.card=Credit/Debit Card
pt.tve.bill.payment.method.card=Cartão de crédito / débito
en.tve.bill.payment.method.ticket=Deposit Ticket
pt.tve.bill.payment.method.ticket=Boleto
en.tve.bill.payment.method.bank_transfer=Bank Transfer
pt.tve.bill.payment.method.bank_transfer=Transferência bancária
en.tve.bill.payment.method.e-wallet=e-Wallet
pt.tve.bill.payment.method.e-wallet=e-Wallet
#order status
tve.bill.payment.orderstatus.en.payment_pending=Payment Processing
tve.bill.payment.orderstatus.pt.payment_pending=Processando o pagamento
tve.bill.payment.orderstatus.en.payment_succeeded=Payment Succeed
tve.bill.payment.orderstatus.pt.payment_succeeded=Pagamento bem sucedido
tve.bill.payment.orderstatus.en.payment_failed=Payment Failed
tve.bill.payment.orderstatus.pt.payment_failed=Falha no pagamento
tve.bill.payment.orderstatus.en.payment_cancelled=Payment Expired
tve.bill.payment.orderstatus.pt.payment_cancelled=Pagamento expirado
tve.bill.payment.orderstatus.en.refund_pending=Refunding
tve.bill.payment.orderstatus.pt.refund_pending=Reembolsando
tve.bill.payment.orderstatus.en.refund_rejected=Refund Rejected
tve.bill.payment.orderstatus.pt.refund_rejected=Reembolso Rejeitado
tve.bill.payment.orderstatus.en.refund_succeeded=Refunded
tve.bill.payment.orderstatus.pt.refund_succeeded=Reembolsado
tve.bill.payment.orderstatus.en.refund_cancelled=Refund Expired
tve.bill.payment.orderstatus.pt.refund_cancelled=Reembolso expirado
tve.bill.payment.orderstatus.en.chargeback_pending=Chargeback Processing
tve.bill.payment.orderstatus.pt.chargeback_pending=Processando o estorno
tve.bill.payment.orderstatus.en.chargeback_rejected=Chargeback Rejected
tve.bill.payment.orderstatus.pt.chargeback_rejected=Estorno Rejeitado
tve.bill.payment.orderstatus.en.chargeback_cancelled=Chargeback Expired
tve.bill.payment.orderstatus.pt.chargeback_cancelled=Estorno expirado
tve.bill.payment.orderstatus.en.chargeback_succeeded=Chargeback Completed
tve.bill.payment.orderstatus.pt.chargeback_succeeded=Estorno concluído
#payment type
tve.bill.payment.type.pt.full=À vista
tve.bill.payment.type.en.full=Full price
tve.bill.payment.type.pt.installments=Parcelas
tve.bill.payment.type.en.installments=Installments
#for payment ingo field.
tve.payer.firstname.min.length=1
tve.payer.firstname.max.length=50
tve.payer.lastname.min.length=1
tve.payer.lastname.max.length=50
tve.payer.email.min.length=1
tve.payer.email.max.length=40
\ No newline at end of file
tve.member.user.auth.ip=
#Call payment gateway api
#tve.payment.gateway.api.url=http://120.77.200.186
tve.payment.gateway.api.url=http://127.0.0.1:2054
tve.payment.gateway.api.readTimeOut=60000
tve.payment.gateway.api.connectTimeOut=60000
#Goods api address
#tve.product.api.url=http://localhost:2098
tve.product.api.url=http://127.0.0.1:2098
tve.product.api.readTimeOut=60000
tve.product.api.connectTimeOut=60000
#User api address
tve.user.api.url=http://192.168.31.110:2099
tve.user.api.readTimeOut=60000
tve.user.api.connectTimeOut=60000
#oauth服务器地址
tve.oauth.server.host=52.83.177.217:6242
#payment gateway call front page url
tve.bill.payment.callback.url=http://www.aixuegao.cn/paymentResult?orderId={orderId}&paymentMethod={paymentMethod}&cardType={cardType}
#payment gateway call tve bill url
tve.bill.payment.notification.url=http://192.168.31.110:2094/api/payment/updatedInvoice/v1
#payment gateway secret
tve.bill.payment.gateway.appid=1001
tve.bill.payment.gateway.secret=d6sg8GmFZ655Bxl8XFDKMxTjHhuYhv3O
<!DOCTYPE HTML>
<html lang="en" xmlns="http://www.w3.org/1999/html">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<title>Renew</title>
</head>
<br>
<p><span><strong>[[${tveServiceInfo}]]</strong></span></p>
<p><b><span>[[${mfcServiceInfo}]]</span></b></p>
<p><b><span>[[${hotServiceInfo}]]</span></b></p>
<br/>
<br>
<p>Thanks for shopping with us. Your purchase comes with a free HOT renewal code! [[${installmentsMessage}]]</p>
<br/>
<br>
<p>If you already have an email account, go to "My Account", click on "Renew now" and enter your TVE renewal code valid for {<span>[[${validate}]]</span>} days.
Whereas, if you haven't registered an email account yet, use the renewal code directly to login under "Login via Renewal Code".
However, we highly recommend you register first.</p>
<br/>
<br>
<p>Try our new HOT APP for [[${validate}]] days FOR FREE!Download the HOT APP from GetApps on your TV box or go to www.tvexpress.pro. Use the above free code to log in.</p>
<br/>
<br>
<p><span>[[${mfcMessage}]]</span></p>
<br/>
<br>
<p>If you need additional help, please contact tvecustomer@gmail.com</p>
<br/>
<br>
<p>Thanks!</p>
<br/>
<p>TVExpress</p>
<p>http://www.tvexpress.pro/</p>
</body>
</html>
\ No newline at end of file
<!DOCTYPE HTML>
<html lang="en" xmlns="http://www.w3.org/1999/html">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<title>Renew</title>
</head>
<br>
<p><span><strong>[[${tveServiceInfo}]]</strong></span></p>
<p><b><span>[[${mfcServiceInfo}]]</span></b></p>
<p><b><span>[[${hotServiceInfo}]]</span></b></p>
<br/>
<p>Thanks for shopping with us. You have chosen [[${installments}]] installments. Please, check your bank statement.</p>
<br/>
<p>If you already have an email account, go to "My Account", click on "Renew now" and enter your TVE renewal code valid for {<span>[[${validate}]]</span>} days. Whereas, if you haven't registered an email account yet, use the renewal code directly to login under "Login via Renewal Code". However, we highly recommend you register first.</p>
<br/>
<p>Your purchase comes with a free HOT renewal code! Try our new HOT APP for [[${validate}]] days FOR FREE!Download the HOT APP from GetApps on your TV box or go to www.tvexpress.pro. Use the above free code to log in.</p>
<br/>
<p>If you need additional help, please contact tvecustomer@gmail.com</p>
<br/>
<br/>
<p>Thanks.</p>
<br/>
<p>TVExpress.</p>
<p>http://www.tvexpress.pro/</p>
</body>
</html>
\ No newline at end of file
<!DOCTYPE HTML>
<html lang="en" xmlns="http://www.w3.org/1999/html">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<title>Renew</title>
</head>
<br>
<p><span><strong>[[${tveServiceInfo}]]</strong></span></p>
<p><b><span>[[${mfcServiceInfo}]]</span></b></p>
<p><b><span>[[${hotServiceInfo}]]</span></b></p>
<br/>
<p>Obrigado pela sua compra. Você escolheu realizar o pagamento em [[${installments}]] parcelas. Por favor, verifique seu extrato bancário.</p>
<br/>
<p>Se já possui uma conta de e-mail, acesse "Minha Conta", clique em "Renovar agora" e insira seu código TVE válido por {<span>[[${validate}]]</span>} dias. Caso ainda não possua uma conta de e-mail, use o código de recarga para fazer login diretamente na opção "Login via Código de Recarga". Entretanto, recomendamos que você se registre primeiro.</p>
<br/>
<p>O seu plano vem com um código de recarga grátis para o aplicativo HOT! Teste nosso novo APP HOT por [[${validate}]] dias GRÁTIS! Baixe o APP HOT na GetApps da sua TV Box ou acesse www.tvexpress.pro. Use o código que te presenteamos para realizar o login.</p>
<br/>
<p>Caso tenha outras dúvidas ou consultas, entre em contato: tvecustomer@gmail.com</p>
<br/>
<br/>
<p>Obrigado!</p>
<br/>
<p>TVExpress.</p>
<p>http://www.tvexpress.pro/</p>
</body>
</html>
\ No newline at end of file
<!DOCTYPE HTML>
<html lang="en" xmlns="http://www.w3.org/1999/html">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<title>Renew</title>
</head>
<br>
<p><span><strong>[[${tveServiceInfo}]]</strong></span></p>
<p><b><span>[[${mfcServiceInfo}]]</span></b></p>
<p><b><span>[[${hotServiceInfo}]]</span></b></p>
<br/>
<br>
<p>Obrigado pela sua compra. O seu plano vem com um código de recarga grátis para o aplicativo HOT! [[${installmentsMessage}]]</p>
<br/>
<br>
<p>Se já possui uma conta de e-mail, acesse "Minha Conta", clique em "Recarregar agora" e insira seu código TVE válido por {<span>[[${validate}]]</span>} dias.
Caso ainda não possua uma conta de e-mail, use o código de recarga para fazer login diretamente na opção "Login via Código de Recarga".
Entretanto, recomendamos que você se registre primeiro. </p>
<br/>
<br>
<p>Teste nosso novo APP HOT por [[${validate}]] dias GRÁTIS! Baixe o APP HOT na GetApps da sua TV Box ou acesse www.tvexpress.pro.
Use o código que te presenteamos para realizar o login.</p>
<br/>
<br>
<p><span>[[${mfcMessage}]]</span></p>
<br/>
<br>
<p>Caso tenha outras dúvidas ou consultas, entre em contato: tvecustomer@gmail.com</p>
<br/>
<br>
<p>Obrigado!</p>
<br/>
<p>TVExpress</p>
<p>http://www.tvexpress.pro/</p>
</body>
</html>
\ No newline at end of file
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<title>Renew</title>
</head>
<br>
<p><strong>TVE: Account Renewed Successfully</strong></p>
<p><span><strong>[[${mfcServiceInfo}]]</strong></span></p>
<p><span><strong>[[${hotServiceInfo}]]</strong></span></p>
<br/>
<p>Thanks for shopping with us. [[${installmentsMessage}]]</p>
<br/>
<p>{<span>[[${validate}]]</span>} days of valid service has been automatically added to your account <span style='font-weight:bold;color:rgb(147,112,219)'>[[${account}]]</span>. Expiration Date: {<span>[[${expirationDate}]]</span>};</p>
<br/>
<p>Your purchase comes with a free HOT renewal code! Try our new HOT APP for <span>[[${validate}]]</span> days FOR FREE!</p>
<p>Download the HOT APP from GetApps on your TV box or go to www.tvexpress.pro. Use the above free code to log in.</p>
<br/>
<p><span>[[${mfcMessage}]]</span></p>
<br/>
<p>If you need additional help, please contact suporte@tvexpress.pro</p>
<br/>
<br/>
<p>Thanks!</p>
<br/>
<p>TVExpress</p>
<p>http://www.tvexpress.pro/</p>
</body>
</html>
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<title>Renew</title>
</head>
<br>
<p><strong>TVE: Conta recarregada com sucesso</strong></p>
<p><span><strong>[[${mfcServiceInfo}]]</strong></span></p>
<p><span><strong>[[${hotServiceInfo}]]</strong></span></p>
<br/>
<p>Obrigado pela sua compra. [[${installmentsMessage}]]</p>
<br/>
<p>{<span>[[${validate}]]</span>} dias de serviço válidos foram automaticamente adicionados na conta <span style='font-weight:bold;color:rgb(147,112,219)'>[[${account}]]</span>. Data de expiração: {<span>[[${expirationDate}]]</span>};</p>
<br/>
<p>O seu plano vem com um código de recarga grátis para o aplicativo HOT! Teste nosso novo APP HOT por <span>[[${validate}]]</span> dias GRÁTIS! </p>
<p>Baixe o APP HOT na GetApps da sua TV Box ou acesse www.tvexpress.pro. Use o código que te presenteamos para realizar o login.</p>
<br/>
<p><span>[[${mfcMessage}]]</span></p>
<br/>
<p>Caso tenha outras dúvidas ou consultas, entre em contato: suporte@tvexpress.pro</p>
<br/>
<p>Obrigado!</p>
<br/>
<p>TVExpress</p>
<p>http://www.tvexpress.pro/</p>
</body>
</html>
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<title>Renew</title>
</head>
<br>
<p>Dear Customer,</p>
<p style="text-align: center">Your subscription failed!</p>
<p>We are sorry to inform you that your TVE monthly subscribe service renew failed.</p>
<p>Please update your payment card information and purchase a new TVE Monthly Plan to resubscribe it.</p>
<br/>
<p>If you need additional help, please contact suporte@tvexpress.pro</p>
</body>
</html>
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<title>Renew</title>
</head>
<br>
<p>Estimado cliente,</p>
<p style="text-align: center">Sua assinatura falhou!</p>
<p>Lamentamos informar que a renovação do seu serviço de assinatura mensal TVE falhou.</p>
<p>Atualize as informações do seu cartão de pagamento e adquira um novo plano mensal da TVE para se inscrever novamente.</p>
<br/>
<p>Se você precisar de alguma outra ajuda, entre em contato: suporte@tvexpress.pro</p>
</body>
</html>
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<title>Renew</title>
</head>
<br>
<p><span><strong>[[${tveServiceInfo}]]</strong></span></p>
<p><b><span>[[${mfcServiceInfo}]]</span></b></p>
<p><b><span>[[${hotServiceInfo}]]</span></b></p>
<br/>
<p>Thanks for shopping with us. [[${installmentsMessage}]]</p>
<br/>
<p>{<span>[[${validate}]]</span>} days of valid service has been automatically added to your account <span style='font-weight:bold;color:rgb(147,112,219)'>[[${account}]]</span>. Expiration Date: {<span>[[${expirationDate}]]</span>}.</p>
<br/>
<p>Your purchase comes with a free HOT renewal code! Try our new HOT APP for [[${validate}]] days FOR FREE!
Download the HOT APP from GetApps on your TV box or go to www.tvexpress.pro. Use the above free code to log in.</p>
<br/>
<br/>
<p><span>[[${mfcMessage}]]</span></p>
<br/>
<p>If you need additional help, please contact suporte@tvexpress.pro</p>
<br/>
<br/>
<p>Thanks!</p>
<br/>
<p>TVExpress</p>
<p>http://www.tvexpress.pro/</p>
</body>
</html>
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<title>Renew</title>
</head>
<br>
<p><span><strong>[[${tveServiceInfo}]]</strong></span></p>
<p><b><span>[[${mfcServiceInfo}]]</span></b></p>
<p><b><span>[[${hotServiceInfo}]]</span></b></p>
<br/>
<br>
<p>Obrigado pela sua compra. [[${installmentsMessage}]]</p>
<br/>
<br>
<p>{<span>[[${validate}]]</span>} dias de serviço válidos foram automaticamente adicionados na conta <span style='font-weight:bold;color:rgb(147,112,219)'>[[${account}]]</span>. Data de expiração: {<span>[[${expirationDate}]]</span>}.</p>
<br/>
<br>
<p>O seu plano vem com um código de recarga grátis para o aplicativo HOT! Teste nosso novo APP HOT por [[${validate}]] dias GRÁTIS!
Baixe o APP HOT na GetApps da sua TV Box ou acesse www.tvexpress.pro. Use o código que te presenteamos para realizar o login.</p>
<br/>
<br>
<p><span>[[${mfcMessage}]]</span></p>
<br/>
<br>
<p>Caso tenha outras dúvidas ou consultas, entre em contato: suporte@tvexpress.pro</p>
<br/>
<br>
<p>Obrigado!</p>
<br/>
<p>TVExpress</p>
<p>http://www.tvexpress.pro/</p>
</body>
</html>
####################################################
##Config file for control.sh
####################################################
##program directory,default is current directory
APP_DIR=
##app name
APP_NAME=mfc-bill-0.1.0.jar
##app config file
APP_CONF=
##APP_CONF=../conf/application.properties
##jvm options
JAVA_OPTS="-XX:+HeapDumpOnOutOfMemoryError -Xms256m -Xmx1024m"
#!/bin/bash
CUR_DIR=$(cd "$(dirname "$0")"; pwd)
PID_FILE="pid.txt"
#load config
CTRL_CFG=$CUR_DIR/control.config
if [ ! -f "$CTRL_CFG" ] ; then
echo "Control config file[$CTRL_CFG] not exist!";
exit 0
else
source $CTRL_CFG
fi
# default 600 second
if [ -z "${MON_TIME}" ]; then
MON_TIME=600
fi
if [ -z "${APP_DIR}" ]; then
APP_PATH=$CUR_DIR/$APP_NAME
else
APP_PATH=$APP_DIR/$APP_NAME
fi
MON_FILE_PATH=$CUR_DIR/$MON_FILE
TODAY=`date "+%Y-%m-%d"`
MON_LOG="$CUR_DIR/logs/monitor-$TODAY.log"
function log(){
ct=`date "+%Y-%m-%d %H:%M:%S"`
echo "$ct $*" | tee -a $MON_LOG
}
source ~/.bashrc
#use default java sdk
#if [ -z "$JAVA_HOME" ] ; then
# log "JAVA_HOME is not set"
# exit 1
#fi
JAVA=java
ARGS=$1
CMD=
## show command help
function showHelp()
{
echo "Usage control.sh [start|stop|restart|status]"
echo -e "\t start : Start service"
echo -e "\t stop : Stop service"
echo -e "\t restart: Restart service"
echo -e "\t status : Show service status"
}
## get current process id
function currentPid(){
#ps -ef|grep java | grep $APP_NAME |grep -v grep|awk '{print $2}'
echo $(<"$PID_FILE")
}
## check process id
function checkPid(){
cpid=`currentPid`
ps -ef|grep java | grep ${cpid} |grep -v grep|awk '{print $2}'
}
## check service status
function checkActive(){
cpid=`checkPid`
if [ -z "${cpid}" ] ; then
log "Service not exist."
return 1
fi
if [ -f "${MON_FILE_PATH}" ] ; then
lmt=`stat -c %Y ${MON_FILE_PATH}`
ct=`date +%s`
dt=`expr $ct - $lmt`
if [ $dt -gt $MON_TIME ] ; then
log "File[$MON_FILE_PATH] not change from $lmt"
return 1
fi
fi
return 0
}
## start service
function startService()
{
cpid=`checkPid`
if [ ${cpid} ] ; then
log "Service[$APP_NAME] already running,pid($cpid)."
else
log "Start Service:$APP_NAME"
log "JAVA_OPTS:$JAVA_OPTS"
if [ -z "$APP_CONF" ]; then
CMD="$JAVA -jar $JAVA_OPTS $APP_PATH"
log "Run cmd:[$CMD]"
nohup $CMD >/dev/null 2>&1 &
#nohup $CMD >>$CDIR/123.log 2>&1 &
echo $! > $PID_FILE
log "Start service done."
else
CMD="$JAVA -jar $JAVA_OPTS $APP_PATH --spring.config.location=$APP_CONF"
log "Run cmd:[$CMD]"
nohup $CMD >/dev/null 2>&1 &
echo $! > $PID_FILE
log "Start service with config done."
fi
fi
}
#stop service
function stopService()
{
cpid=`checkPid`
if [ ${cpid} ]; then
log "Stop Service[$APP_NAME]($cpid)"
#kill pid and children pids
#ref:http://stackoverflow.com/questions/392022/best-way-to-kill-all-child-processes
#kill -9 $cpid
pkill -9 -P $cpid
sleep 1
log "Kill [$APP_NAME] Children by Parent PID[$cpid]"
kill -9 $cpid
sleep 1
log "Kill [$APP_NAME] PID[$cpid]"
else
log "Stop Service[$APP_NAME] is not running."
fi
}
#restart service
function restartService()
{
log "Restart service[$APP_NAME]"
stopService
sleep 3
startService
}
#show service status
function showStatus()
{
echo "Service[$APP_NAME] status:"
echo "-------------------------------------------------------------"
cpid=`currentPid`
ps -ef|grep java | grep ${cpid} |grep -v grep
if [ ${cpid} ]; then
ps -f --no-headers --ppid ${cpid}
fi
echo "-------------------------------------------------------------"
}
#
function monitorService(){
checkActive
activeStatus=$?
if [ $activeStatus -eq 1 ]; then
log "Service state is abnormal,restart service."
restartService
else
log "Service state is normal."
fi
}
## check args not empty
if [ -z "$ARGS" ]; then
showHelp
exit 0
fi
log "==========================================================="
log "Cmd : $0 $*"
log "Config : $CTRL_CFG"
log "Dir : $CUR_DIR"
log "App : $APP_PATH"
log "Monitor : $MON_FILE($MON_TIME)"
echo ""
## switch control command
case "$ARGS" in
start) startService && sleep 3 && showStatus ;;
stop) stopService && showStatus ;;
restart) restartService && showStatus ;;
status) showStatus ;;
monitor) monitorService;;
*) showHelp ;;
esac
exit 0
\ No newline at end of file
#!/usr/bin/env bash
#######################################
## 程序升级脚本(只支持Springboot程序)
## control.sh必须存在,用于重启程序
## update : 要升级的程序存放路径
## backup : 备份的文件的存放路径
#######################################
CONTROL_SH="control.sh"
UPDATE_FILE=$1
TS=`date "+%Y%m%d%H%M%S"`
UPDATE_DIR=update
BACKUP_DIR=backup
TARGET_FILE="$UPDATE_DIR/$UPDATE_FILE"
BACKUP_FILE="$BACKUP_DIR/$UPDATE_FILE.$TS"
if [ ! -d $UPDATE_DIR ]; then
mkdir $UPDATE_DIR;
fi
if [ ! -d $BACKUP_DIR ]; then
mkdir $BACKUP_DIR;
fi
if [ -z "$UPDATE_FILE" ]; then
echo "Usage: update.sh update_file"
exit 1
fi
if [ ! -f $CONTROL_SH ]; then
echo "$CONTROL_SH NOT exist"
exit -1
fi
if [ ! -f "$TARGET_FILE" ]; then
echo "Update file[$TARGET_FILE] not exist"
exit -1
fi
echo "Backup $UPDATE_FILE"
cp -vf $UPDATE_FILE $BACKUP_FILE
echo "Stop Service"
./control.sh stop
echo "Replace $UPDATE_FILE"
cp -vf $TARGET_FILE $UPDATE_FILE
echo "Start Service"
./control.sh start
mv -vf $TARGET_FILE $TARGET_FILE.deployed
echo "Update $UPDATE_FILE Done."
package com.valor.tve.member.bill;
import common.config.tools.config.ConfigTools3;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
/**
* @author allen.wang
*/
@EnableScheduling
@SpringBootApplication
@EnableTransactionManagement
@ComponentScan(basePackages = {
"com.valor.tve.member.bill",
"com.valor.tve.member.common",
"com.common.web",
"common.web.tools"
})
public class BillMainApplication {
private static final Logger LOG = LoggerFactory.getLogger(BillMainApplication.class);
public static void main(String[] args) {
ConfigTools3.load();
SpringApplication.run(BillMainApplication.class, args);
LOG.info("**************** TVE Bill Start ************************");
}
}
package com.valor.tve.member.bill.api;
import com.valor.tve.member.bill.api.req.TveLockCodeReqDTO;
import com.valor.tve.member.bill.api.resp.CodeRespDTO;
import com.valor.tve.member.common.tools.ReflectTools;
import com.valor.tve.member.common.web.BusinessException;
import common.base.tools.api.model.ApiResponse;
import common.config.tools.config.ConfigTools3;
import org.springframework.stereotype.Service;
import retrofit2.http.Body;
import java.util.HashMap;
import java.util.Map;
@Service
public class CardApi extends CommonApi<CardApiInterface> {
@Override
protected void initParams() throws Exception { }
public CardApi(){}
public CardApi(String url){
setUrl(url);
setApiInterfaceType(CardApiInterface.class);
setReadTimeOut(ConfigTools3.getLong("tve.card.api.readTimeOut", 60_000L));
setConnectTimeOut(ConfigTools3.getLong("tve.card.api.connectTimeOut", 60_000L));
}
public ApiResponse<CodeRespDTO> createOtherCard(Map<String,String> createCardReqMap) throws BusinessException{
return invoke(createCardReqMap, ReflectTools.getCurrentMethodName());
}
public ApiResponse<CodeRespDTO> createTveCode(Map<String,String> createCardReqMap) throws BusinessException{
return invoke(createCardReqMap, ReflectTools.getCurrentMethodName());
}
// public ApiResponse lockTveCode(HashMap<String,String> tveLockCodeReq) throws BusinessException{
// return invoke(tveLockCodeReq, ReflectTools.getCurrentMethodName());
// }
public ApiResponse lockTveCode(TveLockCodeReqDTO tveLockCodeReq) throws BusinessException{
return invoke(tveLockCodeReq, ReflectTools.getCurrentMethodName());
}
public ApiResponse lockOtherCode(Map<String,String> lockOtherCodeReqMap) throws BusinessException{
return invoke(lockOtherCodeReqMap, ReflectTools.getCurrentMethodName());
}
}
package com.valor.tve.member.bill.api;
import com.valor.tve.member.bill.api.req.CreateCodeReqDTO;
import com.valor.tve.member.bill.api.req.TveLockCodeReqDTO;
import com.valor.tve.member.bill.api.resp.CodeRespDTO;
import common.base.tools.api.model.ApiResponse;
import retrofit2.Call;
import retrofit2.http.*;
import java.util.HashMap;
import java.util.Map;
public interface CardApiInterface {
// @POST("/api/admin/accountcard/create/v1")
//// public Call<ApiResponse<CodeResp>> createOtherCard(@QueryMap HashMap<String,String> createCardReqMap);
@POST("/api/admin/accountcard/create/v1")
public Call<ApiResponse<CodeRespDTO>> createOtherCard(@QueryMap Map<String,String> createCardReqMap);
@POST("/api/charge/recharge/create/v2")
public Call<ApiResponse<CodeRespDTO>> createTveCode(@QueryMap Map<String,String> createCardReqMap);
// @POST("/api/tve/oauth/codeRefund/v1")
// public Call<ApiResponse> lockTveCode(@QueryMap HashMap<String,String> tveLockCodeReqMap);
@POST("/api/tve/oauth/codeRefund/v1")
public Call<ApiResponse> lockTveCode(@Body TveLockCodeReqDTO tveLockCodeReqMap);
@POST("/api/user3/notification/rollback/ac/v1")
public Call<ApiResponse> lockOtherCode(@QueryMap Map<String,String> lockOtherCodeReqMap);
}
package com.valor.tve.member.bill.api;
import com.valor.tve.member.api.goods.dto.GoodsSystemPropertiesDTO;
import com.valor.tve.member.api.goods.dto.MemberGoodsDTO;
import com.valor.tve.member.common.web.BusinessException;
import common.base.tools.api.model.ApiPagingResponse;
import common.base.tools.api.model.ApiResponse;
import common.config.tools.config.ConfigTools3;
import org.springframework.stereotype.Service;
import com.valor.tve.member.common.tools.ReflectTools;
import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.List;
@Service
public class GoodsApi extends CommonApi<GoodsApiInterface> {
@PostConstruct
@Override
protected void initParams() throws Exception {
setApiInterfaceType(GoodsApiInterface.class);
setUrl(ConfigTools3.getString("tve.product.api.url"));
setReadTimeOut(ConfigTools3.getLong("tve.product.api.readTimeOut", 60_000L));
setConnectTimeOut(ConfigTools3.getLong("tve.product.api.connectTimeOut", 60_000L));
}
public ApiResponse<List<MemberGoodsDTO>> getGoodsInfo(HashMap<String,String> goodsMap) throws BusinessException {
return invokeHeader(goodsMap, ReflectTools.getCurrentMethodName());
}
public ApiResponse<GoodsSystemPropertiesDTO> getGoodsSystemProperties(HashMap<String,String> goodsMap) throws BusinessException {
return invokeHeader(goodsMap, ReflectTools.getCurrentMethodName());
}
}
package com.valor.tve.member.bill.api;
import com.valor.tve.member.api.goods.dto.GoodsSystemPropertiesDTO;
import com.valor.tve.member.api.goods.dto.MemberGoodsDTO;
import common.base.tools.api.model.ApiResponse;
import retrofit2.Call;
import retrofit2.http.POST;
import retrofit2.http.QueryMap;
import java.util.HashMap;
import java.util.List;
public interface GoodsApiInterface {
@POST("/api/goods/listGoods/v1")
public Call<ApiResponse<List<MemberGoodsDTO>>> getGoodsInfo(@QueryMap HashMap<String,String> goodsMap);
@POST("/api/goods/systemGoodsProperties/v1")
public Call<ApiResponse<GoodsSystemPropertiesDTO>> getGoodsSystemProperties(@QueryMap HashMap<String,String> goodsMap);
}
package com.valor.tve.member.bill.api;
import com.valor.tve.member.bill.api.req.PaymentGatewayInstallmentsReqDTO;
import com.valor.tve.member.bill.api.req.PaymentGatewayPaymentMethodReqDTO;
import com.valor.tve.member.bill.api.req.PaymentGatewayPayReqDTO;
import com.valor.tve.member.bill.api.req.RateReqDTO;
import com.valor.tve.member.bill.api.resp.PaymentGatewayInstallmentsRespDTO;
import com.valor.tve.member.bill.api.resp.PaymentGatewayPaymentMethodRespDTO;
import com.valor.tve.member.bill.api.resp.PaymentGatewayPayRespDTO;
import com.valor.tve.member.bill.api.resp.RateRespDTO;
import com.valor.tve.member.bill.interceptor.PaymentAuthInterceptor;
import com.valor.tve.member.common.tools.ReflectTools;
import com.valor.tve.member.common.web.BusinessException;
import common.base.tools.api.model.ApiPagingResponse;
import common.base.tools.api.model.ApiResponse;
import common.config.tools.config.ConfigTools3;
import okhttp3.Interceptor;
import org.springframework.stereotype.Service;
import retrofit2.Call;
import retrofit2.http.Body;
import javax.annotation.PostConstruct;
import java.util.List;
import java.util.Map;
@Service
public class PaymentApi extends CommonApi<PaymentApiInterface> {
@PostConstruct
@Override
protected void initParams() throws Exception {
setApiInterfaceType(PaymentApiInterface.class);
setUrl(ConfigTools3.getString("tve.payment.gateway.api.url"));
setReadTimeOut(ConfigTools3.getLong("tve.payment.gateway.api.readTimeOut", 60_000L));
setConnectTimeOut(ConfigTools3.getLong("tve.payment.gateway.api.connectTimeOut", 60_000L));
}
@Override
protected Interceptor authInterceptor() {
String appid = ConfigTools3.getString("tve.bill.payment.gateway.appid","1278ff55");
String secret = ConfigTools3.getString("tve.bill.payment.gateway.secret","d6sg8GmFZ655Bxl8XFDKMxTjHhuYhv3O");
String algorithm = "HmacSHA256";
return new PaymentAuthInterceptor(appid, secret, algorithm);
}
public ApiPagingResponse<List<PaymentGatewayPaymentMethodRespDTO>> getPaymentMethod(PaymentGatewayPaymentMethodReqDTO req) throws BusinessException {
return invoke(req, ReflectTools.getCurrentMethodName());
}
public ApiPagingResponse<List<PaymentGatewayPaymentMethodRespDTO>> getMultiPaymentMethod(PaymentGatewayPaymentMethodReqDTO req) throws BusinessException {
return invoke(req, ReflectTools.getCurrentMethodName());
}
public ApiResponse<PaymentGatewayInstallmentsRespDTO> createInstallmentsPlans(PaymentGatewayInstallmentsReqDTO req) throws BusinessException {
return invoke(req, ReflectTools.getCurrentMethodName());
}
public ApiPagingResponse<PaymentGatewayPayRespDTO> requestPayment(PaymentGatewayPayReqDTO req) throws BusinessException {
return invoke(req, ReflectTools.getCurrentMethodName());
}
public ApiResponse<PaymentGatewayPayRespDTO> recent(Map<String,Object> queryMap) throws BusinessException {
return invoke(queryMap, ReflectTools.getCurrentMethodName());
}
/**
* 查询charge back和refund的订单
*/
public ApiResponse<List<PaymentGatewayPayRespDTO>> getChargeBackAndRefundOrder(Map<String,Object> req) throws BusinessException {
return invoke(req, ReflectTools.getCurrentMethodName());
}
public ApiResponse<RateRespDTO> queryRate(RateReqDTO request) throws BusinessException
{
return invoke(request, ReflectTools.getCurrentMethodName());
}
}
package com.valor.tve.member.bill.api;
import com.valor.tve.member.bill.api.req.*;
import com.valor.tve.member.bill.api.resp.PaymentGatewayInstallmentsRespDTO;
import com.valor.tve.member.bill.api.resp.PaymentGatewayPaymentMethodRespDTO;
import com.valor.tve.member.bill.api.resp.PaymentGatewayPayRespDTO;
import com.valor.tve.member.bill.api.resp.RateRespDTO;
import common.base.tools.api.model.ApiPagingResponse;
import common.base.tools.api.model.ApiResponse;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.POST;
import java.util.List;
import java.util.Map;
public interface PaymentApiInterface {
@Deprecated
@POST("/api/pay/methods/v1")
public Call<ApiPagingResponse<List<PaymentGatewayPaymentMethodRespDTO>>> getPaymentMethod(@Body PaymentGatewayPaymentMethodReqDTO request);
@POST("/api/pay/methods/v2")
public Call<ApiPagingResponse<List<PaymentGatewayPaymentMethodRespDTO>>> getMultiPaymentMethod(@Body PaymentGatewayPaymentMethodReqDTO request);
@POST("/api/pay/syncPay/v2")
public Call<ApiPagingResponse<PaymentGatewayPayRespDTO>> requestPayment(@Body PaymentGatewayPayReqDTO request);
@POST("/api/pay/updated/v1")
public Call<ApiPagingResponse<List<PaymentGatewayPayRespDTO>>> getUpdateInvoice(@Body PaymentGatewayUpdateOrderReqDTO request);
@POST("/api/pay/installments/plans/v1")
public Call<ApiPagingResponse<PaymentGatewayInstallmentsRespDTO>> createInstallmentsPlans(@Body PaymentGatewayInstallmentsReqDTO request);
@POST("/api/pay/recent/v1")
public Call<ApiResponse<PaymentGatewayPayRespDTO>> recent(@Body Map<String,Object> queryMap);
@POST("/api/pay/updated/v2")
public Call<ApiResponse<List<PaymentGatewayPayRespDTO>>> getChargeBackAndRefundOrder(@Body Map<String,Object> req);
@POST("/api/pay/rate/v2")
public Call<ApiResponse<RateRespDTO>> queryRate(@Body RateReqDTO request);
}
package com.valor.tve.member.bill.api;
import com.valor.tve.member.api.user.dto.*;
import com.valor.tve.member.common.tools.ReflectTools;
import com.valor.tve.member.common.web.BusinessException;
import common.base.tools.api.model.ApiBaseResponse;
import common.base.tools.api.model.ApiResponse;
import common.config.tools.config.ConfigTools3;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.HashMap;
@Service
public class UserApi extends CommonApi<UserApiInterface>{
@PostConstruct
@Override
protected void initParams() throws Exception {
setApiInterfaceType(UserApiInterface.class);
setUrl(ConfigTools3.getString("tve.user.api.url"));
setReadTimeOut(ConfigTools3.getLong("tve.user.api.readTimeOut", 60_000L));
setConnectTimeOut(ConfigTools3.getLong("tve.user.api.connectTimeOut", 60_000L));
}
public ApiResponse<CardRespDTO> saveCard(SaveCardReqDTO request) throws BusinessException {
return invoke(request, ReflectTools.getCurrentMethodName());
}
public ApiResponse<CardRespDTO> saveBoaCard(SaveCardReqDTO request) throws BusinessException {
return invoke(request, ReflectTools.getCurrentMethodName());
}
public ApiResponse<RenewRespDTO> saveRenew(SaveRenewReqDTO request) throws BusinessException {
return invoke(request, ReflectTools.getCurrentMethodName());
}
public ApiResponse<CardRespDTO> getCardInfo(HashMap<String,String> cardMap) throws BusinessException {
return invokeHeader(cardMap, ReflectTools.getCurrentMethodName());
}
public ApiResponse<Object> updateCard(UpdateCardReqDTO updateCardReqDTO) throws BusinessException {
return invoke(updateCardReqDTO, ReflectTools.getCurrentMethodName());
}
public ApiResponse<Object> subscribeToEventNotifications(SubscribeEventReqDTO subscribeEventReqDTO) throws BusinessException {
return invoke(subscribeEventReqDTO, ReflectTools.getCurrentMethodName());
}
}
package com.valor.tve.member.bill.api;
import com.valor.tve.member.api.user.dto.*;
import com.valor.tve.member.common.tools.ReflectTools;
import com.valor.tve.member.common.web.BusinessException;
import common.base.tools.api.model.ApiBaseResponse;
import common.base.tools.api.model.ApiResponse;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.QueryMap;
import java.util.HashMap;
public interface UserApiInterface {
@POST("/api/account/saveCard/v1")
public Call<ApiResponse<CardRespDTO>> saveCard(@Body SaveCardReqDTO request);
@POST("/api/account/saveCard/boa")
public Call<ApiResponse<CardRespDTO>> saveBoaCard(@Body SaveCardReqDTO request);
@POST("/api/account/saveRenew/v1")
public Call<ApiResponse<RenewRespDTO>> saveRenew(@Body SaveRenewReqDTO request);
@GET("/api/account/getCard/v1")
public Call<ApiResponse<CardRespDTO>> getCardInfo(@QueryMap HashMap<String, String> cardMap);
@POST("/api/account/updateCard/v1")
public Call<ApiResponse<Object>> updateCard(@Body UpdateCardReqDTO updateCardReqDTO);
@POST("/api/account/subscribe/v1")
public Call<ApiResponse<Object>> subscribeToEventNotifications(@Body SubscribeEventReqDTO subscribeEventReqDTO);
}
package com.valor.tve.member.bill.api.req;
import com.valor.tve.member.api.payment.dto.PaymentInfoReqDTO;
import com.valor.tve.member.api.user.dto.CardRespDTO;
import common.base.tools.AbstractPrintable;
public class CardReqDTO extends AbstractPrintable {
private String token;
private String id;
/**
* see: https://api.dlocal.com/secure_cards
*/
private Boolean save = Boolean.TRUE;
/**
* installments number
*/
private String installments;
/**
* Staging policy ID.
* see: https://api.dlocal.com/installments-plans
*/
private String installmentsId;
// public CardReqDTO() {
// }
//
// public CardReqDTO(PaymentInfoReqDTO paymentInfo) {
// this.token = paymentInfo.getCardToken();
// }
//
// public CardReqDTO(CardRespDTO cardResp) {
// this.token = cardResp.getCardToken();
// this.id = cardResp.getCardNo();
// }
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Boolean getSave() {
return save;
}
public void setSave(Boolean save) {
this.save = save;
}
public String getInstallments() {
return installments;
}
public void setInstallments(String installments) {
this.installments = installments;
}
public String getInstallmentsId() {
return installmentsId;
}
public void setInstallmentsId(String installmentsId) {
this.installmentsId = installmentsId;
}
}
package com.valor.tve.member.bill.api.req;
import com.valor.tve.member.api.common.BasicReqDTO;
public class CreateCodeReqDTO extends BasicReqDTO {
//套餐编号
//1000:free trial 1001:one year 2001:one month
private String planId;
//批次号(制tve卡的参数)
private String batchNo;
//批次号(制mfc, hot卡的参数)
private String batchId;
//所属系统
private String systemId;
//制卡人
private String sellerId;
//mfc和hot的有效时常
private String serviceTime;
//有效时长单位
private String serviceTimeUnit;
//制卡后卡的状态
private String locked;
//tve的有效时长
private String bizValue;
public String getPlanId() {
return planId;
}
public void setPlanId(String planId) {
this.planId = planId;
}
public String getBatchNo() {
return batchNo;
}
public void setBatchNo(String batchNo) {
this.batchNo = batchNo;
}
public String getBatchId() {
return batchId;
}
public void setBatchId(String batchId) {
this.batchId = batchId;
}
public String getSystemId() {
return systemId;
}
public void setSystemId(String systemId) {
this.systemId = systemId;
}
public String getSellerId() {
return sellerId;
}
public void setSellerId(String sellerId) {
this.sellerId = sellerId;
}
public String getServiceTime() {
return serviceTime;
}
public void setServiceTime(String serviceTime) {
this.serviceTime = serviceTime;
}
public String getServiceTimeUnit() {
return serviceTimeUnit;
}
public void setServiceTimeUnit(String serviceTimeUnit) {
this.serviceTimeUnit = serviceTimeUnit;
}
public String getLocked() {
return locked;
}
public void setLocked(String locked) {
this.locked = locked;
}
public String getBizValue() {
return bizValue;
}
public void setBizValue(String bizValue) {
this.bizValue = bizValue;
}
}
package com.valor.tve.member.bill.api.req;
import com.valor.tve.member.api.common.BasicReqDTO;
public class CreateTveCodeReqDTO extends BasicReqDTO {
//充值类型
private String chargeType;
//充值时长类型
private String bizType;
//充值时长
private long bizValue;
//超期时间
private long expireTS;
//制卡人
private String sellers;
//批次号
private String batchNo;
//充值类型 目前填2
private int bizSysType;
//是否锁定 1:锁定 0:不锁定
private int locked;
//产品系列 目前为tve_web
private String bizSysGroup;
//属性 目前不填
// private Long properties;
//目前不填
// private Integer plan;
public String getChargeType() {
return chargeType;
}
public void setChargeType(String chargeType) {
this.chargeType = chargeType;
}
public String getBizType() {
return bizType;
}
public void setBizType(String bizType) {
this.bizType = bizType;
}
public long getBizValue() {
return bizValue;
}
public void setBizValue(long bizValue) {
this.bizValue = bizValue;
}
public long getExpireTS() {
return expireTS;
}
public void setExpireTS(long expireTS) {
this.expireTS = expireTS;
}
public String getSellers() {
return sellers;
}
public void setSellers(String sellers) {
this.sellers = sellers;
}
public String getBatchNo() {
return batchNo;
}
public void setBatchNo(String batchNo) {
this.batchNo = batchNo;
}
public int getBizSysType() {
return bizSysType;
}
public void setBizSysType(int bizSysType) {
this.bizSysType = bizSysType;
}
public int getLocked() {
return locked;
}
public void setLocked(int locked) {
this.locked = locked;
}
public String getBizSysGroup() {
return bizSysGroup;
}
public void setBizSysGroup(String bizSysGroup) {
this.bizSysGroup = bizSysGroup;
}
// public Long getProperties() {
// return properties;
// }
//
// public void setProperties(Long properties) {
// this.properties = properties;
// }
// public Integer getPlan() {
// return plan;
// }
//
// public void setPlan(Integer plan) {
// this.plan = plan;
// }
}
package com.valor.tve.member.bill.api.req;
import com.valor.tve.member.api.common.BasicReqDTO;
import common.base.tools.AbstractPrintable;
public class MerchandisesReqDTO extends AbstractPrintable {
//商品名称
private String name;
//数量
private int quantity;
//币种
private String currency;
//单价
private String unitPrice;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
public String getCurrency() {
return currency;
}
public void setCurrency(String currency) {
this.currency = currency;
}
public String getUnitPrice() {
return unitPrice;
}
public void setUnitPrice(String unitPrice) {
this.unitPrice = unitPrice;
}
}
package com.valor.tve.member.bill.api.req;
import com.valor.tve.member.api.common.BasicReqDTO;
import com.valor.tve.member.bill.db.model.order.OrderDDO;
import common.base.tools.AbstractPrintable;
public class OrderInfoReqDTO extends AbstractPrintable {
//订单ID
private Long id;
//订单总价
private String totalPrice;
//订单币种
private String currency;
// public OrderInfoReqDTO() {
// }
//
// public OrderInfoReqDTO(OrderDDO order) {
// this.id = order.getId();
// this.currency = order.getCurrency();
// this.totalPrice = setDLocalPrice(order.getTotalPrice());
// }
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTotalPrice() {
return totalPrice;
}
public void setTotalPrice(String totalPrice) {
this.totalPrice = totalPrice;
}
public String getCurrency() {
return currency;
}
public void setCurrency(String currency) {
this.currency = currency;
}
}
package com.valor.tve.member.bill.api.req;
import com.valor.tve.member.api.common.BasicReqDTO;
import com.valor.tve.member.api.payment.dto.PaymentInfoReqDTO;
import com.valor.tve.member.api.payment.dto.PaymentReqDTO;
import com.valor.tve.member.api.user.dto.CardRespDTO;
import common.base.tools.AbstractPrintable;
public class PayerReqDTO extends AbstractPrintable {
private String firstName;
private String lastName;
private String email;
private String document;
private String userId;
private String clientIp;
private String mobile;
private String birthDate;
public String getClientIp() {
return clientIp;
}
public void setClientIp(String clientIp) {
this.clientIp = clientIp;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getDocument() {
return document;
}
public void setDocument(String document) {
this.document = document;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public String getBirthDate() {
return birthDate;
}
public void setBirthDate(String birthDate) {
this.birthDate = birthDate;
}
}
package com.valor.tve.member.bill.api.req;
import com.valor.tve.member.api.common.BasicReqDTO;
import java.math.BigDecimal;
import java.util.List;
public class PaymentGatewayInstallmentsReqDTO extends BasicReqDTO {
private String country;
private String bin;
private BigDecimal amount;
private String currency;
private String providerId;
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getBin() {
return bin;
}
public void setBin(String bin) {
this.bin = bin;
}
public BigDecimal getAmount() {
return amount;
}
public void setAmount(BigDecimal amount) {
this.amount = amount;
}
public String getCurrency() {
return currency;
}
public void setCurrency(String currency) {
this.currency = currency;
}
public String getProviderId() {
return providerId;
}
public void setProviderId(String providerId) {
this.providerId = providerId;
}
}
package com.valor.tve.member.bill.api.req;
import com.valor.tve.member.api.common.BasicReqDTO;
import com.valor.tve.member.api.payment.dto.PaymentBaseReqDTO;
import com.valor.tve.member.api.payment.dto.PaymentReqDTO;
import com.valor.tve.member.api.user.dto.CardRespDTO;
import com.valor.tve.member.bill.db.model.order.OrderDDO;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
public class PaymentGatewayPayReqDTO extends BasicReqDTO {
//订单号
private String orderId;
//回调URL
private String callbackUrl;
//通知URL
private String notificationUrl;
//支付价格
private String price;
//支付币种
private String currency;
//国家
private String country;
//支付机构
private String providerId;
//支付方式
private String type;
//卡支付ID
private String methodId;
//客户端浏览器信息
private String userAgent;
//客户端IP
private String clientIp;
//产品列表
private List<MerchandisesReqDTO> merchandises;
//支付卡信息
private CardReqDTO card;
//支付用户信息
private PayerReqDTO payer;
//订单信息
private List<OrderInfoReqDTO> orders;
private String redirectUrlSuccess;
private String redirectUrlFail;
public String getRedirectUrlSuccess() {
return redirectUrlSuccess;
}
public void setRedirectUrlSuccess(String redirectUrlSuccess) {
this.redirectUrlSuccess = redirectUrlSuccess;
}
public String getRedirectUrlFail() {
return redirectUrlFail;
}
public void setRedirectUrlFail(String redirectUrlFail) {
this.redirectUrlFail = redirectUrlFail;
}
public String getCallbackUrl() {
return callbackUrl;
}
public void setCallbackUrl(String callbackUrl) {
this.callbackUrl = callbackUrl;
}
public String getNotificationUrl() {
return notificationUrl;
}
public void setNotificationUrl(String notificationUrl) {
this.notificationUrl = notificationUrl;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
public String getCurrency() {
return currency;
}
public void setCurrency(String currency) {
this.currency = currency;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getProviderId() {
return providerId;
}
public void setProviderId(String providerId) {
this.providerId = providerId;
}
public String getMethodId() {
return methodId;
}
public void setMethodId(String methodId) {
this.methodId = methodId;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public List<MerchandisesReqDTO> getMerchandises() {
return merchandises;
}
public void setMerchandises(List<MerchandisesReqDTO> merchandises) {
this.merchandises = merchandises;
}
public CardReqDTO getCard() {
return card;
}
public void setCard(CardReqDTO card) {
this.card = card;
}
public PayerReqDTO getPayer() {
return payer;
}
public void setPayer(PayerReqDTO payer) {
this.payer = payer;
}
public List<OrderInfoReqDTO> getOrders() {
return orders;
}
public void setOrders(List<OrderInfoReqDTO> orders) {
this.orders = orders;
}
public String getOrderId() {
return orderId;
}
public void setOrderId(String orderId) {
this.orderId = orderId;
}
public String getUserAgent() {
return userAgent;
}
public void setUserAgent(String userAgent) {
this.userAgent = userAgent;
}
public String getClientIp() {
return clientIp;
}
public void setClientIp(String clientIp) {
this.clientIp = clientIp;
}
}
package com.valor.tve.member.bill.api.req;
public class PaymentGatewayPaymentMethodReqDTO {
private String country;
private String currency;
private String amount;
private String userId;
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getCurrency() {
return currency;
}
public void setCurrency(String currency) {
this.currency = currency;
}
public String getAmount() {
return amount;
}
public void setAmount(String amount) {
this.amount = amount;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
}
package com.valor.tve.member.bill.api.req;
import com.valor.tve.member.api.common.BasicReqDTO;
public class PaymentGatewayUpdateOrderReqDTO extends BasicReqDTO {
private long beginTime;
private long endTime;
public long getBeginTime() {
return beginTime;
}
public void setBeginTime(long beginTime) {
this.beginTime = beginTime;
}
public long getEndTime() {
return endTime;
}
public void setEndTime(long endTime) {
this.endTime = endTime;
}
}
package com.valor.tve.member.bill.api.req;
import com.valor.tve.member.api.common.BasicReqDTO;
import org.apache.commons.lang3.StringUtils;
public class RateReqDTO extends BasicReqDTO {
private String providerId;
private String from;
private String to;
public String getProviderId() {
return providerId;
}
public void setProviderId(String providerId) {
this.providerId = providerId;
}
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
public String getTo() {
return to;
}
public void setTo(String to) {
this.to = to;
}
@Override
public String toString() {
return "RateReqDTO{" +
"providerId='" + providerId + '\'' +
", from='" + from + '\'' +
", to='" + to + '\'' +
'}';
}
}
package com.valor.tve.member.bill.api.req;
import com.valor.tve.member.api.common.BasicReqDTO;
public class TveLockCodeReqDTO extends BasicReqDTO {
//充值码
private String chargeCode;
//语言
private String lang;
//登录账号(用户邮箱)
private String loginId;
//卡类型 mfc/tve
private String bizSysType;
//账户Id
private String accountId;
//产品系列
private String productSeries;
//退款原因
private String reason;
public String getChargeCode() {
return chargeCode;
}
public void setChargeCode(String chargeCode) {
this.chargeCode = chargeCode;
}
public String getLang() {
return lang;
}
public void setLang(String lang) {
this.lang = lang;
}
public String getLoginId() {
return loginId;
}
public void setLoginId(String loginId) {
this.loginId = loginId;
}
public String getBizSysType() {
return bizSysType;
}
public void setBizSysType(String bizSysType) {
this.bizSysType = bizSysType;
}
public String getAccountId() {
return accountId;
}
public void setAccountId(String accountId) {
this.accountId = accountId;
}
public String getProductSeries() {
return productSeries;
}
public void setProductSeries(String productSeries) {
this.productSeries = productSeries;
}
public String getReason() {
return reason;
}
public void setReason(String reason) {
this.reason = reason;
}
}
package com.valor.tve.member.bill.api.resp;
/**
* @author: Bowen huang
* @date: 2021/02/03
*/
public class CardRespDTO {
private String id;
private String token;
private String holderName;
private String expiration;
private String lastDigits;
private String brand;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public String getHolderName() {
return holderName;
}
public void setHolderName(String holderName) {
this.holderName = holderName;
}
public String getExpiration() {
return expiration;
}
public void setExpiration(String expiration) {
this.expiration = expiration;
}
public String getLastDigits() {
return lastDigits;
}
public void setLastDigits(String lastDigits) {
this.lastDigits = lastDigits;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
}
package com.valor.tve.member.bill.api.resp;
import common.base.tools.AbstractPrintable;
public class CodeRespDTO extends AbstractPrintable {
private String id;
private String accountId;
private String password;
private String status;
public String getAccountId() {
return accountId;
}
public void setAccountId(String accountId) {
this.accountId = accountId;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
package com.valor.tve.member.bill.api.resp;
import common.base.tools.AbstractPrintable;
public class PaymentGatewayAccountInfoRespDTO extends AbstractPrintable {
//加载dlocal支付控件的url
private String jsUrl;
//初始化页面控件使用的密钥
private String apiKey;
public String getJsUrl() {
return jsUrl;
}
public void setJsUrl(String jsUrl) {
this.jsUrl = jsUrl;
}
public String getApiKey() {
return apiKey;
}
public void setApiKey(String apiKey) {
this.apiKey = apiKey;
}
}
package com.valor.tve.member.bill.api.resp;
import common.base.tools.AbstractPrintable;
import java.math.BigDecimal;
import java.util.List;
public class PaymentGatewayInstallmentsRespDTO extends AbstractPrintable {
private String id;
private String country;
private BigDecimal amount;
private String bin;
private String currency;
private List<Installments> installments;
private static class Installments{
private String id;
private BigDecimal installmentAmount;
private BigDecimal totalAmount;
private Integer installments;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public BigDecimal getInstallmentAmount() {
return installmentAmount;
}
public void setInstallmentAmount(BigDecimal installmentAmount) {
this.installmentAmount = installmentAmount;
}
public BigDecimal getTotalAmount() {
return totalAmount;
}
public void setTotalAmount(BigDecimal totalAmount) {
this.totalAmount = totalAmount;
}
public Integer getInstallments() {
return installments;
}
public void setInstallments(Integer installments) {
this.installments = installments;
}
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public BigDecimal getAmount() {
return amount;
}
public void setAmount(BigDecimal amount) {
this.amount = amount;
}
public String getBin() {
return bin;
}
public void setBin(String bin) {
this.bin = bin;
}
public String getCurrency() {
return currency;
}
public void setCurrency(String currency) {
this.currency = currency;
}
public List<Installments> getInstallments() {
return installments;
}
public void setInstallments(List<Installments> installments) {
this.installments = installments;
}
}
package com.valor.tve.member.bill.api.resp;
import common.base.tools.AbstractPrintable;
public class PaymentGatewayPayRespDTO extends AbstractPrintable {
private String orderId ;
private String paymentId ;
private String providerId;
private String methodId;
private String type;
//the value is "direct" or "redirect"
private String flow;
private String status;
private String price;
private String redirectUrl;
private long paymentTime;
private long updateTime;
private int errorCode;
private String errorText;
private String callbackUrl;
private TicketRespDTO ticket;
//boa postpay
private String barcodeNumber;
private String digitableLine;
private CardRespDTO card;
public String getBarcodeNumber() {
return barcodeNumber;
}
public void setBarcodeNumber(String barcodeNumber) {
this.barcodeNumber = barcodeNumber;
}
public String getDigitableLine() {
return digitableLine;
}
public void setDigitableLine(String digitableLine) {
this.digitableLine = digitableLine;
}
public String getProviderId() {
return providerId;
}
public void setProviderId(String providerId) {
this.providerId = providerId;
}
public String getRedirectUrl() {
return redirectUrl;
}
public void setRedirectUrl(String redirectUrl) {
this.redirectUrl = redirectUrl;
}
public long getPaymentTime() {
return paymentTime;
}
public void setPaymentTime(long paymentTime) {
this.paymentTime = paymentTime;
}
public String getOrderId() {
return orderId;
}
public void setOrderId(String orderId) {
this.orderId = orderId;
}
public String getPaymentId() {
return paymentId;
}
public void setPaymentId(String paymentId) {
this.paymentId = paymentId;
}
public String getMethodId() {
return methodId;
}
public void setMethodId(String methodId) {
this.methodId = methodId;
}
public String getFlow() {
return flow;
}
public void setFlow(String flow) {
this.flow = flow;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public long getUpdateTime() {
return updateTime;
}
public void setUpdateTime(long updateTime) {
this.updateTime = updateTime;
}
public int getErrorCode() {
return errorCode;
}
public void setErrorCode(int errorCode) {
this.errorCode = errorCode;
}
public String getErrorText() {
return errorText;
}
public void setErrorText(String errorText) {
this.errorText = errorText;
}
public String getCallbackUrl() {
return callbackUrl;
}
public void setCallbackUrl(String callbackUrl) {
this.callbackUrl = callbackUrl;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
public TicketRespDTO getTicket() {
return ticket;
}
public void setTicket(TicketRespDTO ticket) {
this.ticket = ticket;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public CardRespDTO getCard() {
return card;
}
public void setCard(CardRespDTO card) {
this.card = card;
}
}
package com.valor.tve.member.bill.api.resp;
import common.base.tools.AbstractPrintable;
import java.util.ArrayList;
import java.util.List;
public class PaymentGatewayPaymentMethodRespDTO extends AbstractPrintable {
private String platform;
private String name;
private List<MethodTypeResp> types = new ArrayList<>();
private PaymentGatewayAccountInfoRespDTO account;
public String getPlatform() {
return platform;
}
public void setPlatform(String platform) {
this.platform = platform;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public PaymentGatewayAccountInfoRespDTO getAccount() {
return account;
}
public void setAccount(PaymentGatewayAccountInfoRespDTO account) {
this.account = account;
}
public List<MethodTypeResp> getTypes() {
return types;
}
public void setTypes(List<MethodTypeResp> types) {
this.types = types;
}
public static class MethodTypeResp{
private String type;
private List<MethodItemResp> items = new ArrayList<>();
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public List<MethodItemResp> getItems() {
return items;
}
public void setItems(List<MethodItemResp> items) {
this.items = items;
}
public static class MethodItemResp{
private String platform;
private String code;
private String type;
private String name;
private String logo;
private boolean direct;//是否直接跳转
private boolean redirect;//知否重定向
public String getPlatform() {
return platform;
}
public void setPlatform(String platform) {
this.platform = platform;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLogo() {
return logo;
}
public void setLogo(String logo) {
this.logo = logo;
}
public boolean isDirect() {
return direct;
}
public void setDirect(boolean direct) {
this.direct = direct;
}
public boolean isRedirect() {
return redirect;
}
public void setRedirect(boolean redirect) {
this.redirect = redirect;
}
}
}
}
package com.valor.tve.member.bill.api.resp;
import com.fasterxml.jackson.annotation.JsonIgnore;
import common.base.tools.AbstractPrintable;
import java.util.Objects;
public class RateRespDTO extends AbstractPrintable {
@JsonIgnore
private Integer id;
private String providerId;
private String from;
private String to;
private String rate;
public RateRespDTO() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getProviderId() {
return providerId;
}
public void setProviderId(String providerId) {
this.providerId = providerId;
}
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
public String getTo() {
return to;
}
public void setTo(String to) {
this.to = to;
}
public String getRate() {
return rate;
}
public void setRate(String rate) {
this.rate = rate;
}
@Override
public String toString() {
return "RateRespDTO{" +
"id=" + id +
", providerId='" + providerId + '\'' +
", from='" + from + '\'' +
", to='" + to + '\'' +
", rate='" + rate + '\'' +
'}';
}
}
package com.valor.tve.member.bill.api.resp;
import common.base.tools.AbstractPrintable;
public class TicketRespDTO extends AbstractPrintable {
private String id;
private String type;
private String format;
private String number;
private String expirationDate;
private String barcode;
private String companyName;
private String creatorName;
private String creatorLogo;
private String imageUrl;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getFormat() {
return format;
}
public void setFormat(String format) {
this.format = format;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public String getExpirationDate() {
return expirationDate;
}
public void setExpirationDate(String expirationDate) {
this.expirationDate = expirationDate;
}
public String getBarcode() {
return barcode;
}
public void setBarcode(String barcode) {
this.barcode = barcode;
}
public String getCompanyName() {
return companyName;
}
public void setCompanyName(String companyName) {
this.companyName = companyName;
}
public String getCreatorName() {
return creatorName;
}
public void setCreatorName(String creatorName) {
this.creatorName = creatorName;
}
public String getCreatorLogo() {
return creatorLogo;
}
public void setCreatorLogo(String creatorLogo) {
this.creatorLogo = creatorLogo;
}
public String getImageUrl() {
return imageUrl;
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
}
package com.valor.tve.member.bill.bo;
import common.base.tools.AbstractPrintable;
/**
* @author: Bowen huang
* @date: 2021/02/06
*/
public class PaymentWeight extends AbstractPrintable {
private String providerId;
private int weight;
public String getProviderId() {
return providerId;
}
public void setProviderId(String providerId) {
this.providerId = providerId;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
}
package com.valor.tve.member.bill.channel;
import com.google.common.collect.Lists;
import com.valor.tve.member.api.payment.dto.MultiPaymentMethodTypeResp;
import com.valor.tve.member.api.payment.dto.PaymentMethodReqDTO;
import com.valor.tve.member.bill.api.PaymentApi;
import com.valor.tve.member.bill.api.req.PaymentGatewayPaymentMethodReqDTO;
import com.valor.tve.member.bill.api.resp.PaymentGatewayPaymentMethodRespDTO;
import com.valor.tve.member.bill.bo.PaymentWeight;
import com.valor.tve.member.common.tools.JsonUtil;
import com.valor.tve.member.common.tools.PropertiesTools;
import com.valor.tve.member.common.web.BusinessException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
/**
* @author: Bowen huang
* @date: 2021/02/18
*/
public abstract class AbstractPaymentMethodHandler {
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private PaymentApi paymentApi;
private AbstractPaymentMethodHandler nextHandler;
public List<MultiPaymentMethodTypeResp> handle(PaymentMethodReqDTO req) throws BusinessException{
String country = getCountry(req.getCurrency());
logger.info("[PaymentMethodHandler/handle] country={}", country);
try {
PaymentGatewayPaymentMethodReqDTO pgpMethodReqDTO = new PaymentGatewayPaymentMethodReqDTO();
pgpMethodReqDTO.setAmount(getPaymentPrice(req.getAmount()));
pgpMethodReqDTO.setCurrency(req.getCurrency());
pgpMethodReqDTO.setCountry(country);
List<PaymentGatewayPaymentMethodRespDTO> pgPaymentMethodRespList = paymentApi.getMultiPaymentMethod(pgpMethodReqDTO).getResult();
if (CollectionUtils.isEmpty(pgPaymentMethodRespList)) {
logger.info("payment method returned by the payment gateway is empty, req={}", req);
return Collections.emptyList();
}
List<MultiPaymentMethodTypeResp> multiPaymentMethodTypeResps = buildPaymentMethods(req, pgPaymentMethodRespList);
if (pgPaymentMethodRespList.size() == 1) {
String providerId = pgPaymentMethodRespList.get(0).getPlatform();
return singleChannelProcess(providerId, req, multiPaymentMethodTypeResps);
}
return multiChannelProcess(req, multiPaymentMethodTypeResps);
} catch (BusinessException ex) {
logger.info("[PaymentMethodHandler/handle] get payment method error,country={},amount={},currency={}", country, req.getAmount(), req.getCurrency(), ex);
throw new BusinessException(ex.getErrCode(), "get payment method error." + ex.getMessage());
}
}
/**
* The specified call chain sequence displayed
*
* @return
*/
public abstract int order();
public AbstractPaymentMethodHandler getNextHandler() {
return nextHandler;
}
public void setNextHandler(AbstractPaymentMethodHandler nextHandler) {
this.nextHandler = nextHandler;
}
/**
* The specific process implemented by the subclass
*
* @param req
* @param multiPaymentMethodTypeResps
* @return
*/
protected abstract List<MultiPaymentMethodTypeResp> multiChannelProcess(final PaymentMethodReqDTO req,
final List<MultiPaymentMethodTypeResp> multiPaymentMethodTypeResps);
/**
* The specific process implemented by the subclass
*
* @param singleProviderId
* @param req
* @param multiPaymentMethodTypeResps
* @return
*/
protected abstract List<MultiPaymentMethodTypeResp> singleChannelProcess(final String singleProviderId,
final PaymentMethodReqDTO req,
final List<MultiPaymentMethodTypeResp> multiPaymentMethodTypeResps);
/**
* Randomly select channels based on weight configuration
*
* @param uid
* @param method
* @param paymentWeights
* @return
*/
protected String randomWeight(Long uid, String method, List<PaymentWeight> paymentWeights) {
int sum = paymentWeights.stream().mapToInt(PaymentWeight::getWeight).sum();
ThreadLocalRandom random = ThreadLocalRandom.current();
int num = random.nextInt(sum);
String result = null;
int left = 0;
for ( PaymentWeight pw : paymentWeights ) {
if ( num < left + pw.getWeight() ) {
result = pw.getProviderId();
logger.info("Chosen provider: uid={}, method={}, provider={}, random={}, paymentWeights={}",
uid, method, pw.getProviderId(), num, paymentWeights);
break;
} else {
left += pw.getWeight();
}
}
return result;
}
/**
* payment method of constructing the website through the data returned by the payment gateway
*
* Mainly set up multiple languages
*
* @param req
* @param pgPaymentMethodRespList
* @return
*/
private List<MultiPaymentMethodTypeResp> buildPaymentMethods(PaymentMethodReqDTO req, List<PaymentGatewayPaymentMethodRespDTO> pgPaymentMethodRespList) {
Objects.requireNonNull(pgPaymentMethodRespList);
logger.info("[PaymentService/buildPaymentMethod] pgPaymentMethodRespList={}", JsonUtil.jsonWithoutError(pgPaymentMethodRespList));
List<MultiPaymentMethodTypeResp> paymentMethodRespList = new ArrayList<>();
for (PaymentGatewayPaymentMethodRespDTO pgPaymentMethodResp : pgPaymentMethodRespList) {
logger.info("[PaymentService/buildPaymentMethod] pgPaymentMethodResp={}", pgPaymentMethodResp);
List<PaymentGatewayPaymentMethodRespDTO.MethodTypeResp> pgMethodTypeRespList = pgPaymentMethodResp.getTypes();
logger.info("[PaymentService/buildPaymentMethod] pgMethodTypeRespList={}", JsonUtil.jsonWithoutError(pgMethodTypeRespList));
if (pgMethodTypeRespList == null && pgMethodTypeRespList.size() <= 0) {
logger.info("[PaymentService/buildPaymentMethod] get empty payment gateway payment method");
continue;
}
for (PaymentGatewayPaymentMethodRespDTO.MethodTypeResp pgPethodTypeResp : pgMethodTypeRespList) {
MultiPaymentMethodTypeResp paymentMethodResp = new MultiPaymentMethodTypeResp();
paymentMethodResp.setProviderId(pgPaymentMethodResp.getPlatform());
paymentMethodResp.setProviderName(pgPaymentMethodResp.getName());
if (pgPaymentMethodResp.getAccount() != null) {
paymentMethodResp.setJsUrl(pgPaymentMethodResp.getAccount().getJsUrl());
paymentMethodResp.setApiKey(pgPaymentMethodResp.getAccount().getApiKey());
}
List<PaymentGatewayPaymentMethodRespDTO.MethodTypeResp.MethodItemResp> pgMethodItemRespList = pgPethodTypeResp.getItems();
logger.info("[PaymentService/buildPaymentMethod] pgMethodItemRespList = {}", JsonUtil.jsonWithoutError(pgMethodItemRespList));
if (pgMethodItemRespList == null || pgMethodItemRespList.size() <= 0) {
logger.info("[PaymentService/buildPaymentMethod] get empty payment gateway payment method item");
continue;
}
List<MultiPaymentMethodTypeResp.MethodItemResp> methodItemResps = Lists.newArrayListWithCapacity(pgMethodItemRespList.size());
for (PaymentGatewayPaymentMethodRespDTO.MethodTypeResp.MethodItemResp pgMethodItemResp : pgMethodItemRespList) {
MultiPaymentMethodTypeResp.MethodItemResp methodItemResp = new MultiPaymentMethodTypeResp.MethodItemResp();
BeanUtils.copyProperties(pgMethodItemResp, methodItemResp);
methodItemResps.add(methodItemResp);
}
paymentMethodResp.setPaymentMethodText(PropertiesTools.getString(req.getLanguage() + ".tve.bill.payment.method." + pgPethodTypeResp.getType()));
paymentMethodResp.setPaymentMethod(pgPethodTypeResp.getType());
paymentMethodResp.setPaymentMethodItems(methodItemResps);
paymentMethodRespList.add(paymentMethodResp);
logger.info("[PaymentService/buildPaymentMethod] paymentMethodResp={}", paymentMethodResp);
}
}
logger.info("[PaymentService/buildPaymentMethod] paymentMethodRespList={}", paymentMethodRespList);
return paymentMethodRespList;
}
/**
* 获取实际的价格(从分到元),保留两位小数
*/
private String getPaymentPrice(int price) {
return new BigDecimal(price + "").divide(new BigDecimal("100")).setScale(2, RoundingMode.HALF_EVEN).toPlainString();
}
/**
* 根据币种获取国际
*/
private String getCountry(String currency) {
return PropertiesTools.getString("tve.bill.payment.currency.country." + currency.toLowerCase(), "BR");
}
}
package com.valor.tve.member.bill.channel;
import com.alibaba.fastjson.JSONArray;
import com.valor.tve.member.api.payment.dto.MultiPaymentMethodTypeResp;
import com.valor.tve.member.api.payment.dto.PaymentMethodReqDTO;
import com.valor.tve.member.bill.bo.PaymentWeight;
import com.valor.tve.member.bill.db.PaymentRuleDao;
import com.valor.tve.member.bill.db.model.order.PaymentRuleDDO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* @author: Bowen huang
* @date: 2021/02/18
*/
@Service
public class GoodsRuleHandler extends AbstractPaymentMethodHandler{
@Autowired
private PaymentRuleDao paymentRuleDao;
@Override
protected List<MultiPaymentMethodTypeResp> multiChannelProcess(PaymentMethodReqDTO reqDTO, final List<MultiPaymentMethodTypeResp> multiPaymentMethodTypeResps) {
if (CollectionUtils.isEmpty(multiPaymentMethodTypeResps)) {
return Collections.emptyList();
}
List<PaymentRuleDDO> paymentRules = paymentRuleDao.getPaymentRule(reqDTO.getGoodsId());
boolean paymentRuleEmpty = CollectionUtils.isEmpty(paymentRules);
if (paymentRuleEmpty) {
AbstractPaymentMethodHandler nextHandler = getNextHandler();
if (nextHandler != null) {
return nextHandler.multiChannelProcess(reqDTO, multiPaymentMethodTypeResps);
}
}
logger.info("payment channel strategy for goodsId={} is {}.", reqDTO.getGoodsId(), paymentRules);
List<MultiPaymentMethodTypeResp> result = new ArrayList<>();
for (PaymentRuleDDO paymentRule : paymentRules) {
List<PaymentWeight> paymentWeights = JSONArray.parseArray(paymentRule.getRule(), PaymentWeight.class);
String providerId = randomWeight(reqDTO.getUid(), paymentRule.getPaymentMethod(), paymentWeights);
MultiPaymentMethodTypeResp multiPaymentMethodTypeResp =
multiPaymentMethodTypeResps.stream()
.filter(
m -> StringUtils.equalsIgnoreCase(m.getPaymentMethod(), paymentRule.getPaymentMethod()) &&
StringUtils.equalsIgnoreCase(providerId, m.getProviderId())
).findFirst().orElse(null);
if (multiPaymentMethodTypeResp != null) {
result.add(multiPaymentMethodTypeResp);
}
}
return result;
}
@Override
protected List<MultiPaymentMethodTypeResp> singleChannelProcess(final String singleProviderId,
final PaymentMethodReqDTO reqDTO,
final List<MultiPaymentMethodTypeResp> multiPaymentMethodTypeResps) {
if (CollectionUtils.isEmpty(multiPaymentMethodTypeResps)) {
return Collections.emptyList();
}
List<PaymentRuleDDO> paymentRules = paymentRuleDao.getPaymentRule(reqDTO.getGoodsId());
if (CollectionUtils.isEmpty(paymentRules)) {
return multiPaymentMethodTypeResps;
}
logger.info("payment channel strategy for goodsId={} is {}.", reqDTO.getGoodsId(), paymentRules);
List<MultiPaymentMethodTypeResp> result = new ArrayList<>();
for (PaymentRuleDDO paymentRule : paymentRules) {
MultiPaymentMethodTypeResp multiPaymentMethodTypeResp =
multiPaymentMethodTypeResps.stream()
.filter(
m -> StringUtils.equals(m.getPaymentMethod(), paymentRule.getPaymentMethod()) &&
StringUtils.equals(singleProviderId, m.getProviderId())
).findFirst().orElse(null);
if (multiPaymentMethodTypeResp != null) {
result.add(multiPaymentMethodTypeResp);
}
}
return result;
}
@Override
public int order() {
return 0;
}
}
package com.valor.tve.member.bill.channel;
import com.valor.tve.member.api.payment.dto.MultiPaymentMethodTypeResp;
import com.valor.tve.member.api.payment.dto.PaymentMethodReqDTO;
import com.valor.tve.member.bill.constant.BillCode;
import com.valor.tve.member.common.tools.PropertiesTools;
import com.valor.tve.member.common.web.BusinessException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import javax.annotation.PostConstruct;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author: Bowen huang
* @date: 2021/02/03
*/
@Service
public class PaymentMethodHandlerExecute {
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private List<AbstractPaymentMethodHandler> handlerList = new LinkedList<>();
private AbstractPaymentMethodHandler handler;
/**
* Processing payment methods according to different strategies
*
* @param req
* @return
* @throws BusinessException
*/
public List<MultiPaymentMethodTypeResp> getMultiPaymentMethod(PaymentMethodReqDTO req) throws BusinessException {
Objects.requireNonNull(req);
if (!req.checkArg()) {
logger.info("Get payment method failure - Invalid args. req={}", req);
throw new BusinessException(BillCode.ERR_BILL_INVALID_ARGS, "Get payment method failure - Invalid args.");
}
return sort(handler.handle(req));
}
@PostConstruct
public void afterPostConstruct() {
if (!CollectionUtils.isEmpty(handlerList)) {
handlerList = handlerList.stream().sorted(Comparator.comparing(AbstractPaymentMethodHandler::order)).collect(Collectors.toList());
for (int i = 1; i < handlerList.size(); i++) {
AbstractPaymentMethodHandler currentHandler = handlerList.get(i - 1);
AbstractPaymentMethodHandler nextHandler = handlerList.get(i);
//Link the processors into a linked list
currentHandler.setNextHandler(nextHandler);
}
this.handler = handlerList.get(0);
}
}
/**
* Payment method sort
*
* @param multiPaymentMethodTypeResps
* @return
*/
private List<MultiPaymentMethodTypeResp> sort(List<MultiPaymentMethodTypeResp> multiPaymentMethodTypeResps) {
if (CollectionUtils.isEmpty(multiPaymentMethodTypeResps)) {
return Collections.emptyList();
}
Map<String,String> orderings = PropertiesTools.getMap("tve.bill.payment.method.sort");
return multiPaymentMethodTypeResps.stream()
.sorted(Comparator.comparingInt(left -> Integer.parseInt(orderings.get(left.getPaymentMethod()))))
.collect(Collectors.toList());
}
}
package com.valor.tve.member.bill.channel;
import com.valor.tve.member.api.order.dto.OrderReqDTO;
import com.valor.tve.member.api.payment.dto.MultiPaymentMethodTypeResp;
import com.valor.tve.member.api.payment.dto.PaymentMethodReqDTO;
import com.valor.tve.member.bill.constant.Constant;
import com.valor.tve.member.bill.db.OrderDao;
import com.valor.tve.member.bill.db.PayerInfoDao;
import com.valor.tve.member.bill.db.model.order.OrderDDO;
import com.valor.tve.member.bill.db.model.order.PayerInfoDDO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* @author: Bowen huang
* @date: 2021/02/18
*/
@Service
public class PaymentRecordHandler extends AbstractPaymentMethodHandler{
@Autowired
private PayerInfoDao payerInfoDao;
@Autowired
private OrderDao orderDao;
@Override
protected List<MultiPaymentMethodTypeResp> multiChannelProcess(final PaymentMethodReqDTO reqDTO, final List<MultiPaymentMethodTypeResp> multiPaymentMethodTypeResps) {
PayerInfoDDO payerInfo = payerInfoDao.getPayerInfo(reqDTO.getUid());
String providerId = null;
if (payerInfo != null) {
providerId = payerInfo.getProviderId();
logger.info("Payer info data already exists for this uid={},payment channel={}.", reqDTO.getUid(), providerId);
}else {
OrderReqDTO orderReqDTO = new OrderReqDTO();
orderReqDTO.setPageIndex(1);
orderReqDTO.setPageSize(1);
orderReqDTO.setUid(reqDTO.getUid());
List<OrderDDO> orderList = orderDao.getOrderList(orderReqDTO);
if (!CollectionUtils.isEmpty(orderList)) {
providerId = Constant.CHANNEL_DLOCAL;
logger.info("uid={} user has no payer info data, and there is data in the order form, " +
"and it is judged as an old user.payment channel={}", reqDTO.getUid(), providerId);
}
}
if (StringUtils.isBlank(providerId)) {
AbstractPaymentMethodHandler nextHandler = getNextHandler();
if (nextHandler != null) {
return nextHandler.multiChannelProcess(reqDTO, multiPaymentMethodTypeResps);
}
}
List<MultiPaymentMethodTypeResp> result = new ArrayList<>();
for (MultiPaymentMethodTypeResp m : multiPaymentMethodTypeResps) {
if (StringUtils.equalsIgnoreCase(m.getPaymentMethod(), "E-WALLET") ||
StringUtils.equalsIgnoreCase(m.getPaymentMethod(), "BANK_TRANSFER") ||
StringUtils.equalsIgnoreCase(providerId, m.getProviderId())) {
result.add(m);
}
}
return result;
}
@Override
protected List<MultiPaymentMethodTypeResp> singleChannelProcess(String singleProviderId, PaymentMethodReqDTO req, List<MultiPaymentMethodTypeResp> multiPaymentMethodTypeResps) {
return Collections.emptyList();
}
@Override
public int order() {
return 1;
}
}
package com.valor.tve.member.bill.channel;
import com.alibaba.fastjson.JSONArray;
import com.valor.tve.member.api.payment.dto.MultiPaymentMethodTypeResp;
import com.valor.tve.member.api.payment.dto.PaymentMethodReqDTO;
import com.valor.tve.member.bill.bo.PaymentWeight;
import com.valor.tve.member.bill.constant.Constant;
import com.valor.tve.member.bill.db.ConfigDao;
import com.valor.tve.member.bill.db.model.order.ConfigDDO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @author: Bowen huang
* @date: 2021/02/18
*/
@Service
public class ProviderWeightHandler extends AbstractPaymentMethodHandler{
@Autowired
private ConfigDao configDao;
@Override
protected List<MultiPaymentMethodTypeResp> multiChannelProcess(final PaymentMethodReqDTO reqDTO, final List<MultiPaymentMethodTypeResp> multiPaymentMethodTypeResps) {
if (CollectionUtils.isEmpty(multiPaymentMethodTypeResps)) {
return Collections.emptyList();
}
ConfigDDO config = configDao.getConfig(Constant.PAYMENT_BASE_TYPE, Constant.PAYMENT_CHILD_TYPE);
if (config ==null || StringUtils.isBlank(config.getValue())) {
logger.info("Global settings are not configured correctly, config={}", config);
return Collections.emptyList();
}
logger.info("The global configuration of payment channel distribution is {}.", config.getValue());
String value = config.getValue();
List<PaymentWeight> paymentWeights = JSONArray.parseArray(value, PaymentWeight.class);
String providerId = randomWeight(reqDTO.getUid(),"*", paymentWeights);
Map<String, List<MultiPaymentMethodTypeResp>> methodGroup =
multiPaymentMethodTypeResps.stream().collect(Collectors.groupingBy(MultiPaymentMethodTypeResp::getPaymentMethod));
List<MultiPaymentMethodTypeResp> result = new ArrayList<>();
for (List<MultiPaymentMethodTypeResp> resps : methodGroup.values()) {
if (resps.size() > 1) {
List<MultiPaymentMethodTypeResp> collect =
resps.stream().filter(m -> StringUtils.equals(providerId, m.getProviderId())).collect(Collectors.toList());
result.addAll(collect);
continue;
}
result.addAll(resps);
}
if (!CollectionUtils.isEmpty(result)) {
return result;
}
AbstractPaymentMethodHandler nextHandler = getNextHandler();
if (nextHandler != null) {
return nextHandler.multiChannelProcess(reqDTO, multiPaymentMethodTypeResps);
}
return Collections.emptyList();
}
@Override
protected List<MultiPaymentMethodTypeResp> singleChannelProcess(String singleProviderId, PaymentMethodReqDTO req, List<MultiPaymentMethodTypeResp> multiPaymentMethodTypeResps) {
return Collections.emptyList();
}
@Override
public int order() {
return 2;
}
}
package com.valor.tve.member.bill.config;
import common.config.tools.config.ConfigTools3;
import common.web.tools.http.HttpTools;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.List;
public class CachingContentFilter implements Filter {
private static final Logger logger = LoggerFactory.getLogger(CachingContentFilter.class);
@Override
public void init(FilterConfig config) throws ServletException {
logger.info("Filter init: {}", config.getServletContext());
}
@Override
public void destroy() {
logger.info("Filter destroy.");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
if ( request instanceof HttpServletRequest ) {
HttpServletRequest hr = (HttpServletRequest) request;
String method = hr.getMethod();
String remote = HttpTools.getRemoteHost(hr);
String uri = hr.getRequestURI();
String query = hr.getQueryString();
List<String> excludes = ConfigTools3.getAsList("tve.member.web.filter.excludes");
if ( !excludes.contains(uri) ) {
logger.info("Filter request: method={}, remote={}, uri={}, query={}", method, remote, uri, query);
}
request = new MultipleReadHttpRequestWrapper(hr);
}
chain.doFilter(request, response);
}
}
package com.valor.tve.member.bill.config;
import com.zaxxer.hikari.HikariDataSource;
import common.config.tools.config.ConfigTools3;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import java.util.Properties;
@Configuration
@EnableTransactionManagement
public class DatabaseConfiguration {
@Bean
public HikariDataSource dataSource() {
HikariDataSource datasource = new HikariDataSource();
datasource.setDriverClassName(ConfigTools3.getString("tve.member.bill.db.driver", "com.mysql.jdbc.Driver"));
datasource.setConnectionInitSql(ConfigTools3.getString("tve.member.bill.db.connectionInitSql","SELECT 1"));
datasource.setJdbcUrl(ConfigTools3.getString("tve.member.bill.db.url"));
datasource.setUsername(ConfigTools3.getString("tve.member.bill.db.username"));
datasource.setPassword(ConfigTools3.getString("tve.member.bill.db.password"));
datasource.setAutoCommit(ConfigTools3.getBoolean("tve.member.bill.db.connection.autoCommit", true));
datasource.setConnectionTimeout(ConfigTools3.getLong("tve.member.bill.db.connection.connectionTimeoutMs", 2000L));
datasource.setIdleTimeout(ConfigTools3.getLong("tve.member.bill.db.connection.idleTimeoutMs", 600_000L));
datasource.setMaxLifetime(ConfigTools3.getLong("tve.member.bill.db.connection.maxLifeTime", 1_800_000L));
datasource.setConnectionTestQuery(ConfigTools3.getString("tve.member.bill.db.connection.connectionTestQuery", null));
datasource.setMinimumIdle(ConfigTools3.getInt("tve.member.bill.db.connection.minimumIdle", 2));
datasource.setMaximumPoolSize(ConfigTools3.getInt("tve.member.bill.db.connection.maximumPoolSize", 5));
datasource.setInitializationFailTimeout(ConfigTools3.getLong("tve.member.bill.db.connection.initializationFailTimeout", 1L));
datasource.setIsolateInternalQueries(ConfigTools3.getBoolean("tve.member.bill.db.connection.isolateInternalQueries", false));
datasource.setAllowPoolSuspension(ConfigTools3.getBoolean("tve.member.bill.db.connection.allowPoolSuspension", false));
datasource.setReadOnly(ConfigTools3.getBoolean("tve.member.bill.db.connection.readOnly", false));
return datasource;
}
@Bean
public LocalSessionFactoryBean sessionFactory(@Autowired HikariDataSource dataSource) {
LocalSessionFactoryBean bean = new LocalSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setPackagesToScan("com.valor.tve.member.bill.db.model");
bean.setHibernateProperties(this.getHibernateProperties());
return bean;
}
@Bean
public PlatformTransactionManager transactionManager(@Autowired SessionFactory sessionFactory) {
HibernateTransactionManager txManager = new HibernateTransactionManager();
txManager.setSessionFactory(sessionFactory);
//txManager.setDefaultTimeout(ConfigTools3.getInt("tve.member.product.db.transactionTimeout",6000));
return txManager;
}
private Properties getHibernateProperties() {
Properties props = new Properties();
props.put("hibernate.dialect", ConfigTools3.getString("tve.member.bill.db.dialect","org.hibernate.dialect.MySQL57InnoDBDialect"));
props.put("hibernate.show_sql", ConfigTools3.getBoolean("tve.member.bill.db.showSql", false));
props.put("hibernate.generate_statistics", ConfigTools3.getBoolean("tve.member.bill.db.statistics", false));
props.put("hibernate.hbm2ddl.auto", ConfigTools3.getString("tve.member.bill.db.hbm2ddlAuto", "update"));
props.put("hibernate.format_sql", ConfigTools3.getString("tve.member.bill.db.formatSql", false));
props.put("hibernate.use_sql_comments", true);
props.put("hibernate.connection.CharSet", "utf8");
props.put("hibernate.connection.characterEncoding", "utf8");
props.put("hibernate.connection.useUnicode", true);
props.put("hibernate.autoReconnect", true);
props.put("hibernate.current_session_context_class", "org.springframework.orm.hibernate5.SpringSessionContext");
props.put("hibernate.cache.use_second_level_cache", ConfigTools3.getBoolean("tve.member.bill.db.useL2Cache", false));
props.put("hibernate.cache.use_query_cache", ConfigTools3.getBoolean("tve.member.bill.db.useQueryCache", false));
props.put("hibernate.globally_quoted_identifiers", false);
props.put("hibernate.globally_quoted_identifiers_skip_column_definitions", true);
return props;
}
}
package com.valor.tve.member.bill.config;
import com.google.common.collect.Iterables;
import com.valor.tve.member.common.tools.RandomUtils;
import org.apache.commons.io.IOUtils;
import org.apache.http.NameValuePair;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.entity.ContentType;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class MultipleReadHttpRequestWrapper extends HttpServletRequestWrapper {
private ByteArrayOutputStream cached = null;
private Map<String, String[]> parameterMap;
private final String id;
public MultipleReadHttpRequestWrapper(HttpServletRequest request) {
super(request);
this.id = RandomUtils.getLocalString(12, RandomUtils.DIGIT);
}
public String getId() {
return id;
}
@Override
public Map<String, String[]> getParameterMap() {
if (parameterMap == null) {
Map<String, Set<String>> map = new LinkedHashMap<>();
decode(getQueryString(), map);
decode(getPostBodyAsString(), map);
Map<String, String[]> result = new LinkedHashMap<>();
map.forEach((key, values) -> {
ArrayList<String> al = new ArrayList<>(values);
String[] a = al.toArray(new String[values.size()]);
result.put(key, a);
});
parameterMap = Collections.unmodifiableMap(result);
}
return parameterMap;
}
@Override
public String getParameter(String key) {
Map<String, String[]> parameterMap = getParameterMap();
String[] values = parameterMap.get(key);
return values != null && values.length > 0 ? values[0] : null;
}
@Override
public String[] getParameterValues(String key) {
Map<String, String[]> parameterMap = getParameterMap();
return parameterMap.get(key);
}
private String getPostBodyAsString() {
try {
if (cached == null) {
cacheInputStream();
}
return cached.toString(getCharacterEncoding());
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
private static void fillMap(Iterable<NameValuePair> params, Map<String, Set<String>> map) {
for (NameValuePair pair : params) {
String key = pair.getName();
String value = pair.getValue();
if (map.containsKey(key)) {
Set<String> values = map.get(key);
values.add(value);
} else {
Set<String> values = new LinkedHashSet<>();
values.add(value);
map.put(key, values);
}
}
}
private Iterable<NameValuePair> decodeParams(String body) {
Iterable<NameValuePair> params = URLEncodedUtils.parse(body, StandardCharsets.UTF_8);
try {
String cts = getContentType();
if (cts != null) {
ContentType ct = ContentType.parse(cts);
if (ct.getMimeType().equals(ContentType.APPLICATION_FORM_URLENCODED.getMimeType())) {
List<NameValuePair> postParams = URLEncodedUtils.parse(IOUtils.toString(getReader()), StandardCharsets.UTF_8);
params = Iterables.concat(params, postParams);
}
}
} catch (IOException ex) {
throw new IllegalStateException(ex);
}
return params;
}
private void decode(String query, Map<String, Set<String>> map) {
if (query != null) {
fillMap(decodeParams(query), map);
}
}
@Override
public String getCharacterEncoding() {
return StandardCharsets.UTF_8.name();
}
private void cacheInputStream() throws IOException {
cached = new ByteArrayOutputStream();
IOUtils.copy(super.getInputStream(), cached);
}
@Override
public ServletInputStream getInputStream() throws IOException {
if (cached == null) {
cacheInputStream();
}
return new MultipleReadInputStream();
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(getInputStream(), StandardCharsets.UTF_8));
}
private class MultipleReadInputStream extends ServletInputStream {
private final ByteArrayInputStream input;
MultipleReadInputStream() {
input = new ByteArrayInputStream(cached.toByteArray());
}
@Override
public boolean isFinished() {
return input.available() > 0;
}
@Override
public boolean isReady() {
return true;
}
@Override
public void setReadListener(ReadListener readListener) {
}
@Override
public int read() throws IOException {
return input.read();
}
@Override
public synchronized void reset() throws IOException {
input.reset();
}
}
}
\ No newline at end of file
package com.valor.tve.member.bill.config;
import common.config.tools.config.ConfigTools3;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Properties;
@Configuration
public class PropertiesConfiguration {
private static final Logger logger = LoggerFactory.getLogger(PropertiesConfiguration.class);
@Bean
public PropertyPlaceholderConfigurer properties() {
PropertyPlaceholderConfigurer configurer = new PropertyPlaceholderConfigurer();
configurer.setIgnoreResourceNotFound(true);
Properties all = new Properties();
StringBuilder sb = new StringBuilder("====================================================================");
ConfigTools3.getAllConfig().forEach((key, value) -> {
all.put(key, value);
sb.append("\n").append(key).append("=").append(value);
});
sb.append("\n====================================================================");
logger.info("All properties: \n{}\n", sb.toString());
configurer.setProperties(all);
return configurer;
}
}
package com.valor.tve.member.bill.config;
import common.config.tools.config.ConfigTools3;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
@Configuration
public class SchedulerPoolConfig implements SchedulingConfigurer {
private static final Logger LOG = LoggerFactory.getLogger(SchedulerPoolConfig.class);
@Override
public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
String threadNamePrefix = "scheduler-pool-";
int poolSize = ConfigTools3.getInt("mfc.bill.scheduler.pool", 10);
ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
threadPoolTaskScheduler.setPoolSize(poolSize);
threadPoolTaskScheduler.setThreadNamePrefix(threadNamePrefix);
threadPoolTaskScheduler.initialize();
scheduledTaskRegistrar.setTaskScheduler(threadPoolTaskScheduler);
LOG.info("SCHEDULER POOL - Initialized with ThreadNamePrefix='{}',PoolSize='{}'", threadNamePrefix, poolSize);
}
}
package com.valor.tve.member.bill.config;
import common.config.tools.config.ConfigTools3;
import java.util.concurrent.Executor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
@Configuration
@EnableAsync
public class SpringAsyncConfig {
private static final Logger LOG = LoggerFactory.getLogger(SpringAsyncConfig.class);
private static final int PAYMENT_PROCESSOR_CORE_THREADS = ConfigTools3.getInt("bill.payment.processor.core.threads", 2);
private static final int PAYMENT_PROCESSOR_MAX_THREADS = ConfigTools3.getInt("bill.payment.processor.max.threads", 5);
private static final int PAYMENT_PROCESSOR_EVENT_QUEUE_LIMIT = ConfigTools3.getInt("bill.payment.processor.queue.limit", 200);
private static final int GENERAL_PROCESSOR_CORE_THREADS = ConfigTools3.getInt("bill.general.processor.core.threads", 5);
private static final int GENERAL_PROCESSOR_MAX_THREADS = ConfigTools3.getInt("bill.general.processor.max.threads", 10);
private static final int GENERAL_PROCESSOR_EVENT_QUEUE_LIMIT = ConfigTools3.getInt("bill.general.processor.queue.limit", 200);
private static final int METRICS_CORE_THREADS = ConfigTools3.getInt("bill.metrics.core.threads", 2);
private static final int METRICS_MAX_THREADS = ConfigTools3.getInt("bill.metrics.max.threads", 10);
private static final int METRICS_EVENT_QUEUE_LIMIT = ConfigTools3.getInt("bill.metrics.queue.limit", 200);
@Bean(name = "paymentProcessorThreadPool")
public Executor paymentProcessorThreadPool() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(PAYMENT_PROCESSOR_CORE_THREADS);
executor.setMaxPoolSize(PAYMENT_PROCESSOR_MAX_THREADS);
executor.setQueueCapacity(PAYMENT_PROCESSOR_EVENT_QUEUE_LIMIT);
executor.setThreadNamePrefix("BillPaymentProcessor");
executor.initialize();
LOG.info("BillPaymentProcessorThreadPool - Initialized with CorePoolSize=[{}],MaxPoolSize=[{}],QueueLimit=[{}]",
PAYMENT_PROCESSOR_CORE_THREADS, PAYMENT_PROCESSOR_MAX_THREADS, PAYMENT_PROCESSOR_EVENT_QUEUE_LIMIT);
return executor;
}
@Bean(name = "generalProcessorThreadPool")
public Executor generalProcessorThreadPool() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(GENERAL_PROCESSOR_CORE_THREADS);
executor.setMaxPoolSize(GENERAL_PROCESSOR_MAX_THREADS);
executor.setQueueCapacity(GENERAL_PROCESSOR_EVENT_QUEUE_LIMIT);
executor.setThreadNamePrefix("GeneralProcessor");
executor.initialize();
LOG.info("GeneralProcessorThreadPool - Initialized with CorePoolSize=[{}],MaxPoolSize=[{}],QueueLimit=[{}]",
GENERAL_PROCESSOR_CORE_THREADS, GENERAL_PROCESSOR_MAX_THREADS, GENERAL_PROCESSOR_EVENT_QUEUE_LIMIT);
return executor;
}
@Bean(name = "metricsThreadPool")
public Executor metricsThreadPool() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(METRICS_CORE_THREADS);
executor.setMaxPoolSize(METRICS_MAX_THREADS);
executor.setQueueCapacity(METRICS_EVENT_QUEUE_LIMIT);
executor.setThreadNamePrefix("BillMetrics");
executor.initialize();
LOG.info("MetricsThreadPool - Initialized with CorePoolSize=[{}],MaxPoolSize=[{}],QueueLimit=[{}]",
METRICS_CORE_THREADS, METRICS_MAX_THREADS, METRICS_EVENT_QUEUE_LIMIT);
return executor;
}
}
package com.valor.tve.member.bill.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.valor.tve.member.common.interceptor.LogInterceptor;
import com.valor.tve.member.common.tools.JsonUtil;
//import com.valor.tve.member.product.web.interceptor.LogInterceptor;
import org.springframework.boot.web.server.ErrorPage;
import org.springframework.boot.web.server.ErrorPageRegistrar;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.List;
@EnableWebMvc
//@Configuration
public class WebConfiguration implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LogInterceptor()).addPathPatterns("/api/**").excludePathPatterns(
"/api/ping2",
"/api/payment/renewOrder/v1",
"/api/payment/renewPay/v1",
"/api/payment/updatedInvoice/v1",
"/api/payment/method/v1"
);
}
@Bean
public ErrorPageRegistrar errorPageRegistrar() {
return registry -> registry.addErrorPages(
new ErrorPage(HttpStatus.NOT_FOUND, "/404"),
new ErrorPage(HttpStatus.BAD_REQUEST, "/403"),
new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/500"),
new ErrorPage(Throwable.class, "/500")
);
}
@Bean
public FilterRegistrationBean<CachingContentFilter> filterRegistrationBean() {
FilterRegistrationBean<CachingContentFilter> bean = new FilterRegistrationBean<>();
bean.setFilter(new CachingContentFilter());
bean.setOrder(1);
bean.addUrlPatterns("/*");
return bean;
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
ObjectMapper mapper = JsonUtil.createDefault();
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(mapper);
converters.add(0, converter);
}
}
package com.valor.tve.member.bill.constant;
public class BillCode {
public static final String BILL_MODULE = "bill";
public static final int RET_BILL = 1013;
//common error
public static final int ERR_BILL_SYS_ERROR = 9995;
public static final int ERR_BILL_INVALID_ARGS = 9999;
//payment error
public static final int ERR_BILL_GOODS_NOT_FOUND = 1001;//Product not found.
public static final int ERR_BILL_ORDER_NOT_FOUND = 1002;//order not found
public static final int ERR_BILL_PAYMENT_REQUEST_FREQUENT = 1003;//operation too frequent.
public static final int ERR_BILL_CARD_NOT_FOUND = 1004;//card not found
public static final int ERR_BILL_ORDER_STATUS_ERROR = 1005;//order status error
public static final int ERR_BILL_SAVE_CARD_ERROR = 1006;//save card exception
public static final int ERR_BILL_SAVE_RENEW_ERROR = 1009;//save card exception
public static final int ERR_BILL_SAME_ORDER_STATUS = 1007;//get same order status
public static final int ERR_BILL_INVALID_PAYMENT_GATEWAY_RESPONSE = 1008;//invalid payment gate way response date
public static final int ERR_BILL_CARD_DISABLED = 1010;//card is disabled
public static final int ERR_BILL_UPDATE_CARD_ERROR = 1011;//update card error
public static final int SUBSCRIPTION_EVENT_NOTIFICATION_FAILED = 1012;//Subscription event notification failed
public static final int ERR_BILL_PAYMENT_ARGS_INVALID_FIRST_NAME = 1104;//Invalid first name
public static final int ERR_BILL_PAYMENT_ARGS_INVALID_LAST_NAME = 1105;//Invalid last name
public static final int ERR_BILL_PAYMENT_ARGS_INVALID_DOCUMENT = 1106;//Invalid document
public static final int ERR_BILL_PAYMENT_ARGS_INVALID_EMAIL = 1107;//Invalid email
public static final int ERR_BILL_AUTO_CHARGE_ERROR = 1201; //auto charge exception
public static final int ERR_BILL_CREATE_TVE_CODE_ERROR = 1202; //charge tve code charge response
public static final int ERR_BILL_CREATE_OTHER_CODE_ERROR = 1203; //charge tve code charge response
//Call api error
public static final int ERR_BILL_API_ERROR = 20000;
public static final int ERR_BILL_API_IO_EXCEPTION = 20001;
}
package com.valor.tve.member.bill.constant;
public class Constant {
//退款定时器执行时加锁的UID
public static final long CHARGEBACK_USER_ID = -1L;
//调用oauth模块锁卡时返回码
public static final int OAUTH_LOCK_CODE_MODULE = 800;
//调用oauth模块锁卡时错误码(表示用户已经退过款)
public static final int OAUTH_LOCK_CODE_HAVE_EXECUTED = 113;
//自动续费
public static final Integer AUTO_RENEW = 1;
//不分期,表示全期付款
public static final String NOT_INSTALLMENT = "1";
public static final String PAYMENT_BASE_TYPE = "payment";
public static final String PAYMENT_CHILD_TYPE = "weight";
public static final String CHANNEL_DLOCAL = "DLOCAL";
}
package com.valor.tve.member.bill.constant;
/**
* 用户直冲返回的状态吗
*/
public enum EChargeRespStatus {
SUCCESS(1),USER_NOT_EXISTS(15),USER_NOT_EXISTS_2(16),REQUEST_CHARGE_FREQUENCY(17),HAVA_CHARGED(18),CHARGE_FAIL(19),;
private int value;
EChargeRespStatus(int value){
this.value = value;
}
public int getValue(){
return value;
}
}
package com.valor.tve.member.bill.constant;
/**
* 服务状态
*/
public enum EServiceStatus {
SUCCESS(1), PARTIAL_SUCCESS(2), FAIL(3);
private int value;
EServiceStatus(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
package com.valor.tve.member.bill.controller;
import com.valor.tve.member.common.tools.HttpUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class BaseController {
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
protected HttpServletRequest request;
@Autowired
protected HttpServletResponse response;
protected String getRemoteRealIp() {
return HttpUtils.getRealRemoteIp(request);
}
protected String getHeader(String name) {
return request.getHeader(name);
}
protected String getUserAgent() {
return getHeader("User-Agent");
}
}
package com.valor.tve.member.bill.controller;
import com.common.web.aop.annotation.WebApiCallV1;
import com.valor.mfc.vms.common.web.response.ResponseList;
import com.valor.tve.member.api.payment.dto.PaymentMethodReqDTO;
import com.valor.tve.member.api.payment.dto.MultiPaymentMethodTypeResp;
import com.valor.tve.member.bill.channel.PaymentMethodHandlerExecute;
import com.valor.tve.member.bill.constant.BillCode;
import com.valor.tve.member.common.tools.JsonUtil;
import com.valor.tve.member.common.web.BusinessException;
import common.web.tools.webapi.annotation.WebApiStatistics;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
/**
* @author: Bowen huang
* @date: 2021/02/03
*/
@Controller
@ResponseBody
@RequestMapping(value = "/api/payment", method = {RequestMethod.GET, RequestMethod.POST})
public class UnifiedPaymentController extends BaseController {
@Autowired
PaymentMethodHandlerExecute paymentMethodHandlerExecute;
/**
* 获取支付方式
*/
@WebApiCallV1
@WebApiStatistics
@RequestMapping(value = "/method/v2")
public ResponseList<MultiPaymentMethodTypeResp> getPaymentMethodV2(HttpServletRequest request, HttpServletResponse response,
@RequestBody PaymentMethodReqDTO req) {
ResponseList<MultiPaymentMethodTypeResp> resp = new ResponseList<>();
try {
List<MultiPaymentMethodTypeResp> paymentMethodRespList = paymentMethodHandlerExecute.getMultiPaymentMethod(req);
logger.info("[method/v1] paymentMethodRespList = {}", JsonUtil.jsonWithoutError(paymentMethodRespList));
resp.setResult(paymentMethodRespList);
} catch (BusinessException e) {
logger.error("[paymentMethod/v1]Business Exception.req={}", req, e);
resp.setErrCode(e.getErrCode());
resp.setMessage(BusinessException.getMutiLanguageMessage(req.getLanguage(), BillCode.BILL_MODULE, e.getErrCode()));
} catch (Exception ex) {
logger.error("[paymentMethod/v1]Other Exception,req={}", req, ex);
resp.setErrCode(BillCode.ERR_BILL_SYS_ERROR);
resp.setMessage(BusinessException.getMutiLanguageMessage(req.getLanguage(), BillCode.BILL_MODULE, BillCode.ERR_BILL_SYS_ERROR));
}
return resp;
}
}
package com.valor.tve.member.bill.db;
import com.valor.mfc.vms.common.database.tool.access.AbstractBaseDao;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import java.lang.reflect.Array;
import java.util.*;
public abstract class BaseDao extends AbstractBaseDao {
protected <E> List<E> query(Class<E> type, Map<String, Object> filter, Map<String, Boolean> sorter) {
return query(type, filter, sorter, 0, 0);
}
protected <E> E unique(Class<E> type, Map<String, Object> filter) {
Criteria criteria = createCriteria(type, filter, null);
List<E> list = criteriaSearch(type, criteria, true, 0, 0);
return list.isEmpty() ? null : list.get(0);
}
protected <E> List<E> query(Class<E> type, Map<String, Object> filter, Map<String, Boolean> sorter, int position, int maxCount) {
Criteria criteria = createCriteria(type, filter, sorter);
return criteriaSearch(type, criteria, false, position, maxCount);
}
private <E> Criteria createCriteria(Class<E> type, Map<String, Object> filter, Map<String, Boolean> sorter) {
Objects.requireNonNull(type, "type");
Session session = currentSession();
Criteria criteria = session.createCriteria(type);
if ( filter != null ) {
for ( Map.Entry<String, Object> entry : filter.entrySet() ) {
String key = entry.getKey();
Object value = entry.getValue();
String op = "eq";
int index = key.lastIndexOf('$');
if ( index > 0 ) {
op = key.substring(index + 1);
key = key.substring(0, index);
}
Criterion criterion;
switch ( op ) {
case "eq":
criterion = value == null ? Restrictions.isNull(key) : Restrictions.eq(key, value);
break;
case "ne":
criterion = value == null ? Restrictions.isNotNull(key) : Restrictions.ne(key, value);
break;
case "gt":
criterion = Restrictions.gt(key, value);
break;
case "ge":
criterion = Restrictions.ge(key, value);
break;
case "lt":
criterion = Restrictions.lt(key, value);
break;
case "le":
criterion = Restrictions.le(key, value);
break;
case "like":
Objects.requireNonNull(value);
criterion = Restrictions.like(key, value.toString(), MatchMode.ANYWHERE);
break;
case "in":
if ( value.getClass().isArray() ) {
int length = Array.getLength(value);
Object[] array = new Object[length];
System.arraycopy(value, 0, array, 0, length);
criterion = Restrictions.in(key, array);
} else if ( value instanceof Collection ) {
criterion = Restrictions.in(key, (Collection<?>)value);
} else {
throw new RuntimeException("Unsupported value type: " + value.getClass());
}
break;
default:
throw new RuntimeException("Unsupported operation: " + op);
}
criteria.add(criterion);
}
}
if ( sorter != null ) {
sorter.forEach((key, asc) -> criteria.addOrder(asc ? Order.asc(key) : Order.desc(key)));
}
return criteria;
}
@SuppressWarnings("unchecked")
private <E> List<E> criteriaSearch(Class<E> type, Criteria criteria, boolean unique, int position, int maxCount) {
// criteria.setResultTransformer(Transformers.aliasToBean(type));
if ( unique ) {
E e = (E) criteria.uniqueResult();
return e == null ? Collections.emptyList() : Collections.singletonList(e);
}
if ( position > 0 ) {
criteria.setFirstResult(position);
}
if ( maxCount > 0 ) {
criteria.setMaxResults(maxCount);
}
return criteria.list();
}
}
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论