@ -1,6 +1,7 @@
package au.com.royalpay.payment.manage.appclient.core.impls ;
import au.com.royalpay.payment.core.PaymentApi ;
import au.com.royalpay.payment.core.exceptions.EmailException ;
import au.com.royalpay.payment.manage.activities.app_index.core.AppActService ;
import au.com.royalpay.payment.manage.analysis.mappers.CustomerAndOrdersStatisticsMapper ;
import au.com.royalpay.payment.manage.analysis.mappers.TransactionAnalysisMapper ;
@ -15,12 +16,7 @@ import au.com.royalpay.payment.manage.mappers.log.*;
import au.com.royalpay.payment.manage.mappers.notice.NoticePartnerMapper ;
import au.com.royalpay.payment.manage.mappers.payment.OrderMapper ;
import au.com.royalpay.payment.manage.mappers.payment.TransactionMapper ;
import au.com.royalpay.payment.manage.mappers.system.ClientAccountMapper ;
import au.com.royalpay.payment.manage.mappers.system.ClientDeviceTokenMapper ;
import au.com.royalpay.payment.manage.mappers.system.ClientMapper ;
import au.com.royalpay.payment.manage.mappers.system.ClientSettleDelayConfMapper ;
import au.com.royalpay.payment.manage.mappers.system.CustomerMapper ;
import au.com.royalpay.payment.manage.mappers.system.ManagerCustomerRelationAlipayMapper ;
import au.com.royalpay.payment.manage.mappers.system.* ;
import au.com.royalpay.payment.manage.merchants.beans.ClientAuthFilesInfo ;
import au.com.royalpay.payment.manage.merchants.beans.ClientUpdateInfo ;
import au.com.royalpay.payment.manage.merchants.core.ClientConfigService ;
@ -28,6 +24,7 @@ import au.com.royalpay.payment.manage.merchants.core.ClientManager;
import au.com.royalpay.payment.manage.merchants.core.ClientModifySupport ;
import au.com.royalpay.payment.manage.merchants.entity.impls.SwitchPermissionModify ;
import au.com.royalpay.payment.manage.notice.beans.NoticeInfo ;
import au.com.royalpay.payment.manage.notice.core.MailService ;
import au.com.royalpay.payment.manage.notice.core.NoticeManage ;
import au.com.royalpay.payment.manage.notice.core.NoticePartner ;
import au.com.royalpay.payment.manage.openim.core.CustomerServiceService ;
@ -40,6 +37,7 @@ import au.com.royalpay.payment.manage.riskbusiness.enums.RiskResultTypeEnum;
import au.com.royalpay.payment.manage.signin.beans.ChangePwdBean ;
import au.com.royalpay.payment.manage.signin.core.SignInAccountService ;
import au.com.royalpay.payment.manage.signin.core.impls.SignInAccountServiceImpl ;
import au.com.royalpay.payment.manage.support.sms.SmsSender ;
import au.com.royalpay.payment.manage.tradelog.beans.TradeLogQuery ;
import au.com.royalpay.payment.manage.tradelog.core.TradeLogService ;
import au.com.royalpay.payment.manage.tradelog.refund.RefundService ;
@ -58,7 +56,9 @@ import au.com.royalpay.payment.tools.merchants.beans.QRCodeConfig;
import au.com.royalpay.payment.tools.merchants.beans.UpdateSurchargeDTO ;
import au.com.royalpay.payment.tools.merchants.core.MerchantInfoProvider ;
import au.com.royalpay.payment.tools.permission.enums.PartnerRole ;
import au.com.royalpay.payment.tools.threadpool.RoyalThreadPoolExecutor ;
import au.com.royalpay.payment.tools.utils.PageListUtils ;
import au.com.royalpay.payment.tools.utils.PasswordUtils ;
import au.com.royalpay.payment.tools.utils.QRCodeUtils ;
import au.com.royalpay.payment.tools.utils.TimeZoneUtils ;
@ -69,7 +69,9 @@ import com.github.miemiedev.mybatis.paginator.domain.Order;
import com.github.miemiedev.mybatis.paginator.domain.PageBounds ;
import com.github.miemiedev.mybatis.paginator.domain.PageList ;
import com.github.qcloudsms.httpclient.HTTPException ;
import org.apache.commons.lang3.ArrayUtils ;
import org.apache.commons.lang3.RandomStringUtils ;
import org.apache.commons.lang3.RandomUtils ;
import org.apache.commons.lang3.StringUtils ;
import org.apache.commons.lang3.time.DateFormatUtils ;
@ -78,9 +80,14 @@ import org.jsoup.Jsoup;
import org.jsoup.nodes.Document ;
import org.slf4j.LoggerFactory ;
import org.springframework.cache.annotation.Cacheable ;
import org.springframework.data.redis.core.StringRedisTemplate ;
import org.springframework.stereotype.Service ;
import org.springframework.transaction.annotation.Transactional ;
import org.springframework.util.Assert ;
import org.thymeleaf.context.Context ;
import org.thymeleaf.spring4.SpringTemplateEngine ;
import java.io.IOException ;
import java.math.BigDecimal ;
import java.math.RoundingMode ;
import java.text.DateFormat ;
@ -186,6 +193,19 @@ public class RetailAppServiceImp implements RetailAppService {
private RiskBusinessService riskBusinessService ;
@Resource
private RiskUploadService riskUploadService ;
@Resource
private MailService mailService ;
@Resource
private RoyalThreadPoolExecutor royalThreadPoolExecutor ;
@Resource
private SpringTemplateEngine thymeleaf ;
@Resource
private StringRedisTemplate stringRedisTemplate ;
@Resource
private SmsSender smsSender ;
private final String BIND_ACCOUNT_EMAIL_PREFIX = "BIND_ACCOUNT_EMAIL" ;
private final String BIND_ACCOUNT_PHONE_PREFIX = "BIND_ACCOUNT_PHONE" ;
private final int BIND_PHONE_TEMPLID = 126978 ;
private Map < String , AppMsgSender > senderMap = new HashMap < > ( ) ;
private final String fileName [ ] = { "client_bank_file" , "client_id_file" , "client_company_file" } ;
@ -1900,4 +1920,144 @@ public class RetailAppServiceImp implements RetailAppService {
RiskResultTypeEnum . WAIT_FOR_AUDIT . getResultType ( ) ) ;
}
@Override
public void bindAccountEmail ( JSONObject device , JSONObject email ) {
String codeKey = device . getString ( "account_id" ) ;
String codeKeyValueRedis = stringRedisTemplate . boundValueOps ( getUpdateAccountEmailKey ( codeKey ) ) . get ( ) ;
if ( StringUtils . isNotEmpty ( codeKeyValueRedis ) ) {
throw new BadRequestException ( "Captcha has been sent.Please check your email or try again in 5 minutes." ) ;
}
String codeKeyValue = RandomStringUtils . random ( 6 , false , true ) ;
Context ctx = new Context ( ) ;
JSONObject account = clientAccountMapper . findById ( device . getString ( "account_id" ) ) ;
ctx . setVariable ( "account" , account ) ;
ctx . setVariable ( "captcha" , codeKeyValue ) ;
final String content = thymeleaf . process ( "mail/account_bind_email.html" , ctx ) ;
royalThreadPoolExecutor . execute ( ( ) - > {
try {
mailService . sendEmail ( "Your account is in the process of binding a mailbox" , email . getString ( "contact_email" ) ,
"" , content ) ;
} catch ( Exception e ) {
throw new EmailException ( "Email Sending Failed" , e ) ;
}
} ) ;
stringRedisTemplate . boundValueOps ( getUpdateAccountEmailKey ( codeKey ) ) . set ( codeKeyValue + "&" + email . getString ( "contact_email" ) , 5 , TimeUnit . MINUTES ) ;
}
@Override
public void updateAccountEmail ( JSONObject device , JSONObject params ) {
String key = stringRedisTemplate . boundValueOps ( getUpdateAccountEmailKey ( device . getString ( "account_id" ) ) ) . get ( ) ;
if ( key = = null ) {
throw new BadRequestException ( "Captcha has expired" ) ;
}
String captcha = key . split ( "&" ) [ 0 ] ;
String email = key . split ( "&" ) [ 1 ] ;
if ( ! StringUtils . equals ( captcha , params . getString ( "captcha" ) ) ) {
throw new BadRequestException ( "Verification code is wrong" ) ;
}
JSONObject account = new JSONObject ( ) ;
account . put ( "account_id" , device . getString ( "account_id" ) ) ;
account . put ( "contact_email" , email ) ;
clientAccountMapper . update ( account ) ;
deleteAccountEmailKey ( device . getString ( "account_id" ) ) ;
}
@Override
public void bindAccountPhone ( JSONObject device , JSONObject phone ) {
String codeKey = device . getString ( "account_id" ) ;
String codeKeyValueRedis = stringRedisTemplate . boundValueOps ( getUpdateAccountPhoneKey ( codeKey ) ) . get ( ) ;
if ( StringUtils . isNotEmpty ( codeKeyValueRedis ) ) {
throw new BadRequestException ( "Captcha has been sent.Please check your phone or try again in 5 minutes." ) ;
}
String codeKeyValue = RandomStringUtils . random ( 6 , false , true ) ;
String nationCode = phone . getString ( "nation_code" ) ;
String phoneNumber = phone . getString ( "contact_phone" ) ;
ArrayList < String > param = new ArrayList < > ( ) ;
param . add ( "绑定手机号" ) ;
param . add ( codeKeyValue ) ;
String expireMin = "5" ;
param . add ( expireMin ) ;
try {
smsSender . getSender ( ) . sendWithParam ( nationCode . trim ( ) , phoneNumber , BIND_PHONE_TEMPLID , param , "RoyalPay" , "" , "" ) ;
} catch ( Exception e ) {
e . printStackTrace ( ) ;
throw new ServerErrorException ( "Phone number is wrong.Please try again." ) ;
}
stringRedisTemplate . boundValueOps ( getUpdateAccountPhoneKey ( codeKey ) ) . set ( codeKeyValue + "&" + nationCode + "&" + phoneNumber , Long . parseLong ( expireMin ) , TimeUnit . MINUTES ) ;
}
@Override
public void updateAccountPhone ( JSONObject device , JSONObject params ) {
String key = stringRedisTemplate . boundValueOps ( getUpdateAccountPhoneKey ( device . getString ( "account_id" ) ) ) . get ( ) ;
if ( key = = null ) {
throw new BadRequestException ( "Captcha has expired" ) ;
}
String captcha = key . split ( "&" ) [ 0 ] ;
String nation_code = key . split ( "&" ) [ 1 ] ;
String contact_phone = key . split ( "&" ) [ 2 ] ;
if ( ! StringUtils . equals ( captcha , params . getString ( "captcha" ) ) ) {
throw new BadRequestException ( "Verification code is wrong" ) ;
}
JSONObject account = new JSONObject ( ) ;
account . put ( "account_id" , device . getString ( "account_id" ) ) ;
account . put ( "contact_phone" , contact_phone ) ;
account . put ( "nation_code" , "+" + nation_code ) ;
clientAccountMapper . update ( account ) ;
deleteAccountPhoneKey ( device . getString ( "account_id" ) ) ;
}
@Override
public void verifyRefundPassword ( JSONObject device , JSONObject json ) {
String clientType = device . getString ( "client_type" ) ;
deviceSupport . findRegister ( clientType ) ;
JSONObject clientConfig = clientConfigService . find ( device . getIntValue ( "client_id" ) ) ;
String needVerifyPassword = json . getString ( "refund_password" ) ;
String refundPwdSalt = clientConfig . getString ( "refund_pwd_salt" ) ;
if ( ! StringUtils . equals ( clientConfig . getString ( "refund_pwd" ) , PasswordUtils . hashPwd ( needVerifyPassword , refundPwdSalt ) ) ) {
throw new BadRequestException ( "Incorrect refund password" ) ;
}
}
@Override
@Transactional
public void resetRefundPassword ( JSONObject device , JSONObject json ) {
String clientType = device . getString ( "client_type" ) ;
deviceSupport . findRegister ( clientType ) ;
JSONObject account = clientAccountMapper . findById ( device . getString ( "account_id" ) ) ;
if ( PartnerRole . getRole ( account . getIntValue ( "role" ) ) ! = PartnerRole . ADMIN ) {
throw new BadRequestException ( "You have no permission" ) ;
}
verifyRefundPassword ( device , json ) ;
String newSalt = PasswordUtils . newSalt ( ) ;
String newPassWord = json . getString ( "new_refund_password" ) ;
if ( ! StringUtils . isNumeric ( newPassWord ) ) {
throw new BadRequestException ( "Refund password must be pure number" ) ;
}
String newPwdHash = PasswordUtils . hashPwd ( newPassWord , newSalt ) ;
if ( StringUtils . equals ( newPwdHash , PasswordUtils . hashPwd ( json . getString ( "refund_password" ) , newSalt ) ) ) {
throw new BadRequestException ( "Old and new passwords cannot be duplicated" ) ;
}
JSONObject update = new JSONObject ( ) ;
update . put ( "client_id" , device . getIntValue ( "client_id" ) ) ;
update . put ( "refund_pwd" , newPwdHash ) ;
update . put ( "refund_pwd_salt" , newSalt ) ;
clientConfigService . update ( update ) ;
}
private void deleteAccountEmailKey ( String codeKey ) {
stringRedisTemplate . delete ( getUpdateAccountEmailKey ( codeKey ) ) ;
}
private void deleteAccountPhoneKey ( String codeKey ) {
stringRedisTemplate . delete ( getUpdateAccountPhoneKey ( codeKey ) ) ;
}
private String getUpdateAccountEmailKey ( String codeKey ) {
return BIND_ACCOUNT_EMAIL_PREFIX + codeKey ;
}
private String getUpdateAccountPhoneKey ( String codeKey ) {
return BIND_ACCOUNT_PHONE_PREFIX + codeKey ;
}
}