小程序后端用什么写代码,小程序的后端用什么写
这里本篇文章使用爪哇进行小程序后端编写,由于公司前段时间要做小程序支付,所以这里把自己写的小程序后端支付控制器记录下来,文档参考微信支付官方文档,地址:https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?第七章索引=1 .
推荐课程:Java教程。
写爬虫互联网协议(互联网协议)被封了怎么解决?立即使用
废话不多说,直接上代码:
PayController
@Api(tags=支付模块)
@RestController
@RequestMapping( )
公共类支付控制器{
@ApiOperation(value=请求支付接口)
@RequestMapping(value=/wxPay ,method=RequestMethod .帖子)
公共JSON对象wxPay(http servlet请求请求){尝试{ //生成的随机字符串
string nonce _ str=getRandomStringByLength(32);//商品名称
字符串体=测试商品名称;//获取客户端的互联网协议(互联网协议的缩写)地址
string sp bill _ create _ IP=getIpAddr(request);//组装参数,用户生成统一下单接口的签名
MapString,String package params=new HashMap();
packageParams.put(appid ,we chatconfig。appid);
packageParams.put(mch_id ,we chat config。mch _ id);
packageParams.put(nonce_str ,nonce _ str);
packageParams.put(body ,body);
包参数。put( out _ trade _ no ,payOrderId );//商户订单号,自己的订单身份
packageParams.put(total_fee ,100 );//支付金额,这边需要转成字符串类型,否则后面的签名会失败
包参数。put( sp bill _ create _ IP ,sp bill _ create _ IP);
packageParams.put(notify_url ,we chat config。notify _ URL);//支付成功后的回调地址
packageParams.put(trade_type ,WechatConfig).贸易类型);//支付方式
packageParams.put(openid ,openId );//用户的openID,自己获取
string prestr=pay util。创建链接字符串(包参数);//把数组所有元素,按照"参数=参数值"的模式用""字符拼接成字符串
//MD5运算生成签名,这里是第一次签名,用于调用统一下单接口
字符串我的符号=支付util。sign(prestr,WechatConfig.key, utf-8 ).toupper case();//拼接统一下单接口使用的可扩展标记语言数据,要将上一步生成的签名一起拼接进去
string XML= XML appid we chat config。appid /appid
身体![CDATA[ body ]]/body
mch _ id 我们聊天配置。mch _ id /mch _ id
nonce_str nonce_str /nonce_str
通知_url 微信配置。通知url /通知URL
openid openid /openid
out _ trade _ no payOrderId /out _ trade _ no
服务提供商计费创建IP 服务提供商计费创建IP /服务提供商计费创建IP
总费用 100 /总费用//支付的金额,单位:分
贸易类型微信配置TRADETYPE /trade_type
签名我的签名/签名
/XML ;//调用统一下单接口,并接受返回的结果
字符串result=pay util。http请求(我们聊天配置。pay _ URL, POST ,XML);//将解析结果存储在模拟中
Map map=PayUtil.doXMLParse(结果);String return _ code=(String)map。get( return _ code );//返回状态码
字符串result _ code=(String)map。get( result _ code )。//返回状态码
MapString,Object response=new hashmap string,Object();//返回给小程序端需要的参数
if(return _ code== SUCCESS return _ code。equals(result _ code)){ String prepay _ id=(String)map。get( prepay _ id )。//返回的预付单信息
回应。put( non centr ,nonce _ str);
response.put(package , prepay _ id= prepay _ id);
长时间戳=系统。当前时间millis()/1000;
response.put(时间戳,时间戳 );//这边要将返回的时间戳转化成字符串,不然小程序端调用wx。请求付款方法会报签名错误
//拼接签名需要的参数
字符串字符串符号temp= appId= wechatconfig。appId nonce str= nonce _ str package=prepay _ id= prepay _ id sign type=MD 5 timeStamp= timeStamp;//再次签名,这个签名用于小程序端调用wx.requesetPayment方法
字符串支付符号=支付工具。sign(字符串符号temp,WechatConfig.key, utf-8 ).toupper case();
response.put(paySign ,paySign);
}
response.put(appid ,we chatconfig。appid);return Response.succ(响应);
} catch(异常e) {
e。printstacktrace();
}返回空
} //这里是支付回调接口,微信支付成功后会自动调用
@ request mapping(value=/wx notify ,method=RequestMethod .帖子)
公共void wx通知(http servlet请求请求,HttpServletResponse响应)引发异常{
缓冲读取器br=新缓冲读取器(新输入流读取器(请求。getinputstream()));字符串行=空
StringBuilder sb=new StringBuilder();while ((line=br.readLine())!=null) {
某人(somebody的简写)追加(行);
}
br。close();//sb为微信返回的可扩展标记语言
字符串notity XML=sb。tostring();字符串resXml=map map=pay util。doxmlprase(notityXml);字符串返回码=(字符串)映射。get( return _ code );如果(成功。equals(returnCode)) { //验证签名是否正确
MapString,String valid params=pay util。para滤波器(map);//回调验签时需要去除符号和空值参数
string prestr=pay util。创建链接字符串(有效参数);
//根据微信官网的介绍,此处不仅对回调的参数进行验签,还需要对返回的金额与系统订单的金额进行比对等
if (PayUtil.verify(prestr,(String) map.get(sign ),WechatConfig.key, utf-8 ){/* *此处添加自己的业务逻辑代码开始**/
//注意要判断微信支付重复回调,支付成功后微信会重复的进行回调
/**此处添加自己的业务逻辑代码end**/
//通知微信服务器已经支付成功
resXml=xml return_code![CDATA[成功]]/return_code
返回_msg![CDATA[OK]]/return _ msg /XML ;
}
}否则{
resXml=xml return_code![CDATA[FAIL]]/return_code
返回_msg![CDATA[报文为空]]/return _ msg /XML ;
}
BufferedOutputStream out=新的BufferedOutputStream(
回应。getoutputstream());
出去。写(resxml。getbytes());
出去。flush();
出去。close();
} //获取随机字符串
私有字符串getRandomStringByLength(int length){ String base= abcdefghijklmnopqrstuvwxyz 0123456789 ;
Random Random=new Random();
字符串缓冲区sb=新字符串缓冲区();for(int I=0;我长度;i ) {
int数=random。nextint(base。length());
某人(somebody的简写)追加(基础。charat(数字));
}回sb。tostring();
} //获取互联网协议(互联网协议)
私有字符串getIpAddr(http servlet请求request){ String IP=request。get标头(“X-Forwarded-For”);if (StringUtils.isNotEmpty(ip)!"未知"。equalsIgnoreCase(ip)) { //多次反向代理后会有多个互联网协议(互联网协议的缩写)值,第一个互联网协议(互联网协议的缩写)才是真实互联网协议(互联网协议的缩写)
int index=ip.indexOf(,);如果(索引!=-1) { return ip.substring(0,索引);
} else {返回ip
}
}
IP=请求。get头( X-Real-IP );if (StringUtils.isNotEmpty(ip)!"未知"。equalsIgnoreCase(IP)){ return IP;
}退货请求。getremote addr();
}
}上面代码用到了帕尤蒂尔和微信配置这两个类,一个是配置类,一个是工具类,代码如下:
PayUtil
公共类PayUtil { /**
* 签名字符串
*
* @param text需要签名的字符串
* @param key密钥
* @param输入_字符集编码格式
* @返回签名结果
*/
公共静态字符串符号(字符串文本、字符串键、字符串输入_字符集){
text=text key= key返回消化工具。MD 5 hex(getContentBytes(text,input _ charset));
} /**
* 签名字符串
*
* @param text需要签名的字符串
* @param符号签名结果
* @param key密钥
* @param输入_字符集编码格式
* @返回签名结果
*/
公共静态布尔验证(字符串文本、字符串符号、字符串键、字符串输入_字符集){
文本=文本键;字符串my sign=digestutils。MD 5 hex(getContentBytes(text,input _ charset));if (mysign.equals(sign)) {返回真实的
}否则{返回错误的
}
} /**
* @param内容
* @param charset
* @返回
* @抛出Java。安全。签名异常
* @ throws UnsupportedEncodingException
*/
public static byte[]get content bytes(String content,String charset){ if(charset==null .equals(charset)){返回内容。getbytes();
}尝试{返回内容。getbytes(charset);
} catch(UnsupportedEncodingException e){ throw new runtime exception( MD5签名过程中出现错误,指定的编码集不对,您目前指定的编码集是: charset);
}
}
私有静态布尔值是有效的char(char ch){ if((ch= 0 ch= 9 ) (ch= A ch= Z ) (ch= A ch= Z ))返回true if((ch=0x4e 00 ch=0x 7 fff) (ch=0x 8000 ch=0x 952 f))返回true//简体中文汉字编码
返回错误的
} /**
* 除去数组中的空值和签名参数
*
* @param sArray签名参数组
* @返回去掉空值与签名参数后的新签名参数组
*/
public static MapString,String paraFilter(MapString,String sArray) { MapString,String result=new HashMapString,String();if(sArray==null sArray。size()=0){返回结果;
} for(字符串键:sarray。keyset()){ String value=sarray。get(键);if(value==null value。等号() 键。equalsignorecase(符号)
键。equalsignorecase( sign _ type ){ continue;
}
结果. put(键,值);
}返回结果;
} /**
* 把数组所有元素排序,并按照"参数=参数值"的模式用""字符拼接成字符串
*
* @param params需要排序并参与字符拼接的参数组
* @返回拼接后字符串
*/
公共静态字符串createLinkString(MapString,String params) {
list string keys=new ArrayList(params。keyset());
集合.排序(键);string prestr=for(int I=0;我钥匙。size();I){ String key=keys。get(I);字符串值=params。get(键);if (i==keys.size() - 1) {//拼接时,不包括最后一个字符
prestr=prestr键=值;
}否则{
prestr=prestr key "=" value
}
} return prestr
} /**
* @param requestUrl请求地址
* @param请求方法请求方法
* @param outputStr参数
*/
公共静态字符串httpRequest(字符串请求Url,字符串请求方法,字符串输出Str) { //创建SSLContext
StringBuffer缓冲区=null尝试{
URL url=新URL(请求URL);
http URL connection conn=(http URL connection)URL。打开连接();
conn.setRequestMethod(请求方法);
conn . setdoooutput(true);
conn . setdoinput(true);
conn . connect();//往服务器端写内容
if (null!=outputStr) {
输出流OS=conn . get输出流();
OS。写(输出字符串。getbytes( utf-8 );
OS。close();
} //读取服务器端返回的内容
InputStream is=conn . getinputstream();
InputStreamReader ISR=new InputStreamReader(is, utf-8 );
BufferedReader br=新缓冲阅读器(ISR);
buffer=新字符串buffer();string line=null while((line=br . readline())!=null) {
缓冲区.附加(行);
}
br。close();
} catch(异常e) {
e。printstacktrace();
}返回缓冲区。tostring();
}
公共静态字符串urlencodeutf 8(字符串源){ String result=source尝试{
结果=Java。网。URL编码器。编码(来源,‘UTF-8’);
} catch(UnsupportedEncodingException e){//TODO自动生成的捕捉块
e。printstacktrace();
}返回结果;
} /**
* 解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的可扩展标记语言数据。
*
* @param strxml
* @返回
* @ throws org。JDOM 2。jdo异常
* @抛出异常
*/
公共静态映射doxmlprase(字符串strxml)引发异常{ if (null==strxml .等于(strxml)) {返回空
} Map m=new HashMap();
InputStream in=string 2 InputStream(strxml);
sax builder builder=new sax builder();
文档doc=构建者。建造(在);
元素根=doc。getrootelement();
list list=root。获取子对象();
迭代器it=列表。迭代器();while (it.hasNext()) {
元素e=(元素)it。next();string k=e . getname();字符串v=
list children=e . get children();if (children.isEmpty()) {
v=e . gettextnormalize();
}否则{
v=getChildrenText(儿童);
}
m.put(k,v);
} //关闭流
英寸close();返回m;
} /**
* 获取子结点的可扩展标记语言
*
* @param儿童
* @返回字符串
*/
公共静态字符串getChildrenText(列出子级){
字符串缓冲区sb=新字符串缓冲区();如果(!children.isEmpty()) {
迭代器它=孩子。迭代器();while (it.hasNext()) {
元素e=(元素)it。next();string name=e . getname();string value=e . gettextnormalize();
list list=e . get children();
某人(somebody的简写)append( name );如果(!list.isEmpty()) {
某人(somebody的简写)append(getChildrenText(list));
}
某人(somebody的简写)追加(值);
某人(somebody的简写)append(/ name );
}
}回sb。tostring();
}
public static InputStream String 2 InputStream(String str){ return new bytearray InputStream(str。getbytes());
}
}WechatConfig
公共类微信配置{ //小程序应用编号
公共静态最终字符串appid=//微信支付的商户编号
公共静态最终字符串mch _ id=//微信支付的商户密钥
公共静态最终字符串密钥="";//支付成功后的服务器回调url,这里填薪酬控制员里的回调函数地址
公共静态最终字符串notify _ URL=“”;//签名方法,固定值
公共静态最终字符串SIGNTYPE= MD5//交易类型,小程序支付的定值是JSAPI
公共静态最终字符串TRADETYPE= JSAPI//微信统一订购接口地址
public static final String pay _ URL= https://API . mch . weixin . QQ . com/pay/unified order ;
}刚开始接触小程序支付的时候,我也觉得比较棘手,因为我没有写支付相关的代码。后来百度查资料,看公文,终于完成了这个支付的控制器。最后,一定要多看几遍公文,再结合PayController的代码看一下,你会发现其实并不是很难支付。以上是小程序后端写的内容细节。更多请关注我们的其他相关文章!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。