parent
064b45639a
commit
8214e507e6
@ -1,33 +1,15 @@
|
|||||||
package au.com.royalpay.payment.manage.support.sms;
|
package au.com.royalpay.payment.manage.support.sms;
|
||||||
|
|
||||||
import com.github.qcloudsms.SmsSingleSender;
|
import au.com.royalpay.payment.manage.support.sms.msg.OpenMessage;
|
||||||
|
import au.com.royalpay.payment.manage.support.sms.msg.RefuseMessage;
|
||||||
|
import au.com.royalpay.payment.manage.support.sms.msg.AuthCodeMessage;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import java.util.Locale;
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
public interface SmsSender {
|
||||||
|
void sendOpenMessage(String nationCode, String mobile, Locale locale, OpenMessage msg);
|
||||||
|
|
||||||
/**
|
void sendAuthCodeMessage(String nationCode, String mobile, Locale locale, AuthCodeMessage register);
|
||||||
* @author kira
|
|
||||||
* @date 2018/8/1
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
public class SmsSender {
|
|
||||||
|
|
||||||
@Value("${royalpay.sms.appid:1400094878}")
|
|
||||||
private int appId;
|
|
||||||
@Value("${royalpay.sms.appkey:43390d81e20c5191c278fbf4cd275be2}")
|
|
||||||
private String appKey;
|
|
||||||
|
|
||||||
private SmsSingleSender sender = null;
|
|
||||||
|
|
||||||
@PostConstruct
|
|
||||||
public void init() {
|
|
||||||
sender = new SmsSingleSender(appId, appKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SmsSingleSender getSender(){
|
|
||||||
return sender;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
void sendRefuseMessage(String nationCode, String mobile, Locale locale, RefuseMessage refuse);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,130 @@
|
|||||||
|
package au.com.royalpay.payment.manage.support.sms;
|
||||||
|
|
||||||
|
import au.com.royalpay.payment.manage.support.sms.daas.DaasMessageTemplate;
|
||||||
|
import au.com.royalpay.payment.manage.support.sms.daas.OpenMessageTemplate;
|
||||||
|
import au.com.royalpay.payment.manage.support.sms.daas.RefuseMessageTemplate;
|
||||||
|
import au.com.royalpay.payment.manage.support.sms.daas.AuthCodeMessageTemplate;
|
||||||
|
import au.com.royalpay.payment.manage.support.sms.msg.OpenMessage;
|
||||||
|
import au.com.royalpay.payment.manage.support.sms.msg.RefuseMessage;
|
||||||
|
import au.com.royalpay.payment.manage.support.sms.msg.AuthCodeMessage;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
|
||||||
|
import org.apache.commons.codec.binary.Base64;
|
||||||
|
import org.joda.time.DateTime;
|
||||||
|
import org.joda.time.DateTimeZone;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
|
import org.springframework.boot.web.client.RestTemplateBuilder;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.http.RequestEntity;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.http.converter.FormHttpMessageConverter;
|
||||||
|
import org.springframework.http.converter.StringHttpMessageConverter;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.util.LinkedMultiValueMap;
|
||||||
|
import org.springframework.util.MultiValueMap;
|
||||||
|
import org.springframework.web.client.RestClientException;
|
||||||
|
import org.springframework.web.client.RestClientResponseException;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
import org.springframework.web.server.ServerErrorException;
|
||||||
|
|
||||||
|
import javax.crypto.Mac;
|
||||||
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.security.InvalidKeyException;
|
||||||
|
import java.security.Key;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@ConditionalOnProperty(value = "royalpay.sms.daas.enable", havingValue = "true")
|
||||||
|
public class SmsSenderDaasImpl implements SmsSender {
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(getClass());
|
||||||
|
private final String serectId;
|
||||||
|
private final String secretKey;
|
||||||
|
private final RestTemplate restTemplate;
|
||||||
|
private static final String URL = "https://service-rzq04n9p-1255701024.sh.apigw.tencentcs.com/release/superapi/super/sms/internation/single";
|
||||||
|
|
||||||
|
public SmsSenderDaasImpl(@Value("${royalpay.sms.daas.secret-id}") String serectId, @Value("${royalpay.sms.daas.secret-key}") String secretKey) {
|
||||||
|
this.serectId = serectId;
|
||||||
|
this.secretKey = secretKey;
|
||||||
|
this.restTemplate = new RestTemplateBuilder().messageConverters(new FormHttpMessageConverter(),
|
||||||
|
new StringHttpMessageConverter(StandardCharsets.UTF_8),
|
||||||
|
new FastJsonHttpMessageConverter())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendOpenMessage(String nationCode, String mobile, Locale locale, OpenMessage msg) {
|
||||||
|
sendSms(nationCode, mobile, new OpenMessageTemplate(msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendAuthCodeMessage(String nationCode, String mobile, Locale locale, AuthCodeMessage register) {
|
||||||
|
sendSms(nationCode, mobile, new AuthCodeMessageTemplate(locale, register));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendRefuseMessage(String nationCode, String mobile, Locale locale, RefuseMessage refuse) {
|
||||||
|
sendSms(nationCode, mobile, new RefuseMessageTemplate(refuse));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendSms(String nationCode, String mobile, DaasMessageTemplate tpl) {
|
||||||
|
MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
|
||||||
|
body.add("mobile", nationCode + mobile.replaceAll("^(\\+61)(61)", ""));
|
||||||
|
body.add("msg", "[RoyalPay]" + tpl.getMessage());
|
||||||
|
RequestEntity<MultiValueMap<String, String>> request = RequestEntity.post(URI.create(URL))
|
||||||
|
.headers(signature()).contentType(MediaType.APPLICATION_FORM_URLENCODED)
|
||||||
|
.body(body);
|
||||||
|
try {
|
||||||
|
ResponseEntity<JSONObject> resp = restTemplate.exchange(request, JSONObject.class);
|
||||||
|
JSONObject respBody = resp.getBody();
|
||||||
|
logger.debug("daas sms response:{}", respBody);
|
||||||
|
Optional.ofNullable(respBody)
|
||||||
|
.map(resBody -> resBody.getJSONArray("data"))
|
||||||
|
.filter(arr -> !arr.isEmpty())
|
||||||
|
.map(dataArr -> dataArr.getJSONObject(0))
|
||||||
|
.ifPresent(data -> {
|
||||||
|
JSONObject record0 = data.getJSONArray("record").getJSONObject(0);
|
||||||
|
logger.info("send sms success:[{}]{}, messageNum:{}", record0.getString("resCode"), record0.getString("resDesc"), data.getString("recordNum"));
|
||||||
|
});
|
||||||
|
} catch (RestClientResponseException e) {
|
||||||
|
logger.error("request sms service failed:[{}]{}", e.getRawStatusCode(), e.getResponseBodyAsString(), e);
|
||||||
|
} catch (RestClientException e) {
|
||||||
|
logger.error("request sms service failed", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private HttpHeaders signature() {
|
||||||
|
String source = "market";
|
||||||
|
String datetime = DateTime.now().withZone(DateTimeZone.UTC).toString("EEE, dd MMM yyyy HH:mm:ss 'GMT'", Locale.ENGLISH);
|
||||||
|
try {
|
||||||
|
String auth = calcAuthorization(source, serectId, secretKey, datetime);
|
||||||
|
MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
|
||||||
|
headers.add("X-Source", source);
|
||||||
|
headers.add("X-Date", datetime);
|
||||||
|
headers.add("Authorization", auth);
|
||||||
|
return new HttpHeaders(headers);
|
||||||
|
} catch (NoSuchAlgorithmException | UnsupportedEncodingException | InvalidKeyException e) {
|
||||||
|
throw new ServerErrorException("Signature failed", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String calcAuthorization(String source, String secretId, String secretKey, String datetime)
|
||||||
|
throws NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeyException {
|
||||||
|
String signStr = "x-date: " + datetime + "\n" + "x-source: " + source;
|
||||||
|
Mac mac = Mac.getInstance("HmacSHA1");
|
||||||
|
Key sKey = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), mac.getAlgorithm());
|
||||||
|
mac.init(sKey);
|
||||||
|
byte[] hash = mac.doFinal(signStr.getBytes(StandardCharsets.UTF_8));
|
||||||
|
String sig = Base64.encodeBase64String(hash);
|
||||||
|
|
||||||
|
return "hmac id=\"" + secretId + "\", algorithm=\"hmac-sha1\", headers=\"x-date x-source\", signature=\"" + sig + "\"";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,65 @@
|
|||||||
|
package au.com.royalpay.payment.manage.support.sms;
|
||||||
|
|
||||||
|
import au.com.royalpay.payment.manage.support.sms.msg.OpenMessage;
|
||||||
|
import au.com.royalpay.payment.manage.support.sms.msg.RefuseMessage;
|
||||||
|
import au.com.royalpay.payment.manage.support.sms.msg.AuthCodeMessage;
|
||||||
|
import au.com.royalpay.payment.tools.exceptions.ServerErrorException;
|
||||||
|
import com.github.qcloudsms.SmsSingleSender;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author kira
|
||||||
|
* @date 2018/8/1
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@ConditionalOnProperty(value = "royalpay.sms.qcloud.enable", havingValue = "true")
|
||||||
|
public class SmsSenderQcloudImpl implements SmsSender {
|
||||||
|
|
||||||
|
private static final int OPEN_MESSAGE_ID = 462770;
|
||||||
|
private static final int REGISTER_CLIENT_TEMPLID_ZH = 126978;
|
||||||
|
private static final int REGISTER_CLIENT_TEMPLID_EN = 346078;
|
||||||
|
private static final int REFUSE_CLIENT_TEMPLID = 166108;
|
||||||
|
private static final int RESET_PASSWORD_TEMPLID = 126978;
|
||||||
|
private final SmsSingleSender sender;
|
||||||
|
private final String sign;
|
||||||
|
|
||||||
|
public SmsSenderQcloudImpl(@Value("${royalpay.sms.qcloud.appid}") int appId, @Value("${royalpay.sms.qcloud.appkey}") String appKey) {
|
||||||
|
sender = new SmsSingleSender(appId, appKey);
|
||||||
|
sign = "RoyalPay";
|
||||||
|
}
|
||||||
|
|
||||||
|
public SmsSingleSender getSender() {
|
||||||
|
return sender;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendOpenMessage(String nationCode, String mobile, Locale locale, OpenMessage msg) {
|
||||||
|
sendMessage(nationCode, mobile, OPEN_MESSAGE_ID, msg.getMaskedPhoneNumber());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendMessage(String nationCode, String mobile, int tplId, String... param) {
|
||||||
|
try {
|
||||||
|
sender.sendWithParam(nationCode, mobile.replace("+61", ""), tplId, param, sign, "", "");
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new ServerErrorException("Phone number is wrong :" + mobile, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendAuthCodeMessage(String nationCode, String mobile, Locale locale, AuthCodeMessage register) {
|
||||||
|
if (locale.equals(Locale.CHINESE) || locale.equals(Locale.SIMPLIFIED_CHINESE)) {
|
||||||
|
sendMessage(nationCode, mobile, REGISTER_CLIENT_TEMPLID_ZH, register.getBiz(), register.getCode(), register.getExpireMin() + "");
|
||||||
|
} else {
|
||||||
|
sendMessage(nationCode, mobile, REGISTER_CLIENT_TEMPLID_EN, register.getBiz(), register.getCode(), register.getExpireMin() + "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendRefuseMessage(String nationCode, String mobile, Locale locale, RefuseMessage refuse) {
|
||||||
|
sendMessage(nationCode, mobile, REFUSE_CLIENT_TEMPLID, refuse.getReason());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package au.com.royalpay.payment.manage.support.sms.daas;
|
||||||
|
|
||||||
|
import org.springframework.util.MultiValueMap;
|
||||||
|
|
||||||
|
public interface DaasMessageTemplate {
|
||||||
|
|
||||||
|
String getMessage();
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package au.com.royalpay.payment.manage.support.sms.msg;
|
||||||
|
|
||||||
|
public class AuthCodeMessage {
|
||||||
|
private final String biz;
|
||||||
|
private final String code;
|
||||||
|
private final int expireMin;
|
||||||
|
|
||||||
|
public AuthCodeMessage(String biz, String code, int expireMin) {
|
||||||
|
this.biz = biz;
|
||||||
|
this.code = code;
|
||||||
|
this.expireMin = expireMin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBiz() {
|
||||||
|
return biz;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getExpireMin() {
|
||||||
|
return expireMin;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
package au.com.royalpay.payment.manage.support.sms.msg;
|
||||||
|
|
||||||
|
public class OpenMessage {
|
||||||
|
private final String phoneNumber;
|
||||||
|
|
||||||
|
|
||||||
|
public OpenMessage(String phoneNumber) {
|
||||||
|
this.phoneNumber = phoneNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMaskedPhoneNumber(){
|
||||||
|
return new StringBuilder(phoneNumber).replace(3,7,"****").toString();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package au.com.royalpay.payment.manage.support.sms.msg;
|
||||||
|
|
||||||
|
public class RefuseMessage {
|
||||||
|
private final String reason;
|
||||||
|
|
||||||
|
public RefuseMessage(String reason) {
|
||||||
|
this.reason = reason;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getReason() {
|
||||||
|
return reason;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
package au.com.royalpay.payment.manage.support.sms.qcloud;
|
||||||
|
|
||||||
|
public interface QCloudMessageTemplate {
|
||||||
|
}
|
Loading…
Reference in new issue