uniapp+java小程序支付

27 篇文章 1 订阅
7 篇文章 0 订阅

1、前端

<template>
	<view class="app">
		<view class="price-box">
			<text>支付金额</text>
			<text class="price">¥{{money}}</text>
		</view>

		<view class="pay-type-list">

			<view class="type-item b-b" @click="changePayType(1)">
				<text class="icon yticon icon-weixinzhifu"></text>
				<view class="con">
					<text class="tit">微信支付</text>
					<text>推荐使用微信支付</text>
				</view>
				<label class="radio">
					<radio value="" color="#fa436a" :checked='payType == 1' />
					</radio>
				</label>
			</view>
			<!-- <view class="type-item b-b" @click="changePayType(2)">
				<text class="icon yticon icon-alipay"></text>
				<view class="con">
					<text class="tit">支付宝支付</text>
				</view>
				<label class="radio">
					<radio value="" color="#fa436a" :checked='payType == 2' />
					</radio>
				</label>
			</view>
			<view class="type-item" @click="changePayType(3)">
				<text class="icon yticon icon-erjiye-yucunkuan"></text>
				<view class="con">
					<text class="tit">预存款支付</text>
					<text>可用余额 ¥198.5</text>
				</view>
				<label class="radio">
					<radio value="" color="#fa436a" :checked='payType == 3' />
					</radio>
				</label>
			</view> -->
		</view>

		<text class="mix-btn" @click="confirm">确认支付</text>
	</view>
</template>

<script>
	import config from '../../common/config.js'
	export default {
		data() {
			return {
				Sign: {
					timeStamp: '',
					nonceStr: '',
					package: '',
					signType: '',
					paySign: ''
				},
				prepay_id: '',
				addressid: '',
				productDesc: '',
				money: 0,
				openid: '',
				goodsData: [],
				payType: 1,
				orderInfo: {}
			};
		},
		computed: {

		},
		created() {

		},
		onLoad(options) {
			this.openid = uni.getStorageSync("openid")

			this.addressid = options.addressid
			this.goodsData = options.goodsData
			this.money = options.total
		},

		methods: {
			pay(){
				var that = this
				uni.requestPayment({
					provider: 'wxpay',
					timeStamp: that.Sign.timeStamp,
					nonceStr: that.Sign.nonceStr,
					package: that.Sign.package,
					signType: that.Sign.signType,
					paySign: that.Sign.paySign,
					success: function(res) {
						uni.redirectTo({
							url: '/pages/money/paySuccess'
						})
						console.log('success:' + JSON.stringify(res));
					},
					fail: function(err) {
						console.log('fail:' + JSON.stringify(err));
					}
				});
			},
			WeiXinSign() {
				var that = this

				uni.request({
					url: config.baseurl + "/API/WeiXinSign",
					method: 'POST',
					dataType: 'json',
					data: JSON.stringify({
						prepay_id: that.prepay_id,
						appid: config.appid

					}),
					headers: {
						'Content-Type': "application/json;charset=utf-8"
					},
					success: function(res) {
						uni.hideLoading()


						that.Sign = res.data
						that.pay()
						// for(var i =0;i<that.cartList.length;i++)
						// {
						// 	console.log(that.cartList[i].id+"_"+that.cartList[i].name)
						// }
					},
					fail(ex) {
						uni.hideLoading()
						uni.showToast({
							title: '请求失败' + ex.message,
							icon: 'none'
						});
					}

				})

			},
			PreXiaDan() {
				uni.showLoading({
					title:'加载中'
				})
				var that = this

				uni.request({
					url: config.baseurl + "/API/WeixinXiadan",
					method: 'POST',
					dataType: 'json',
					data: JSON.stringify({
						openid: that.openid,
						appid: config.appid,
						formcode: config.uuid2(),
						money: that.money,
						productDesc: '社区购'
					}),
					headers: {
						'Content-Type': "application/json;charset=utf-8"
					},
					success: function(res) {
						uni.hideLoading()


						that.prepay_id = res.data.prepay_id
						if(that.prepay_id!="")
						that.WeiXinSign();
						// for(var i =0;i<that.cartList.length;i++)
						// {
						// 	console.log(that.cartList[i].id+"_"+that.cartList[i].name)
						// }
					},
					fail(ex) {
						uni.hideLoading()
						uni.showToast({
							title: '请求失败' + ex.message,
							icon: 'none'
						});
					}

				})
			},
	
			//选择支付方式
			changePayType(type) {
				this.payType = type;
			},
			//确认支付
			confirm: async function() {

				
               this.PreXiaDan()
			   
			},
		}
	}
</script>

<style lang='scss'>
	.app {
		width: 100%;
	}

	.price-box {
		background-color: #fff;
		height: 265upx;
		display: flex;
		flex-direction: column;
		justify-content: center;
		align-items: center;
		font-size: 28upx;
		color: #909399;

		.price {
			font-size: 50upx;
			color: #303133;
			margin-top: 12upx;

			&:before {
				content: '¥';
				font-size: 40upx;
			}
		}
	}

	.pay-type-list {
		margin-top: 20upx;
		background-color: #fff;
		padding-left: 60upx;

		.type-item {
			height: 120upx;
			padding: 20upx 0;
			display: flex;
			justify-content: space-between;
			align-items: center;
			padding-right: 60upx;
			font-size: 30upx;
			position: relative;
		}

		.icon {
			width: 100upx;
			font-size: 52upx;
		}

		.icon-erjiye-yucunkuan {
			color: #fe8e2e;
		}

		.icon-weixinzhifu {
			color: #36cb59;
		}

		.icon-alipay {
			color: #01aaef;
		}

		.tit {
			font-size: $font-lg;
			color: $font-color-dark;
			margin-bottom: 4upx;
		}

		.con {
			flex: 1;
			display: flex;
			flex-direction: column;
			font-size: $font-sm;
			color: $font-color-light;
		}
	}

	.mix-btn {
		display: flex;
		align-items: center;
		justify-content: center;
		width: 630upx;
		height: 80upx;
		margin: 80upx auto 30upx;
		font-size: $font-lg;
		color: #fff;
		background-color: $base-color;
		border-radius: 10upx;
		box-shadow: 1px 2px 5px rgba(219, 63, 96, 0.4);
	}
</style>

2、后端

package com.jbossjf.bootproject.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jbossjf.bootproject.common.*;
import com.jbossjf.bootproject.model.OrderInfo;
import com.jbossjf.bootproject.model.OrderReturnInfo;
import com.jbossjf.bootproject.model.SignInfo;
import com.thoughtworks.xstream.XStream;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

@RestController
public class WeixinController {
    private final Logger L = LoggerFactory.getLogger(WeixinController.class);
    HelpUtils _HelpUtils = new HelpUtils();
    @Autowired
    private HttpServletRequest request;
    @Autowired
    private Environment env;

    //    @Autowired
//    private HttpServletResponse responses;
    @RequestMapping("/wxPay")
    public String wxPay(String openid) {

        try {


        } catch (Exception ex) {
            L.debug(ex.getMessage());
            L.info(ex.getMessage());
            L.error(ex.getMessage());
        }
        return null;
    }

    @RequestMapping("/GetOpenID")
    public String GetOpenID() {
        try {
            String desc = request.getParameter("desc");

            JSONArray jsonArray = JSONArray.parseArray(desc);

            String appid = _HelpUtils.GetJsonArrayValue(jsonArray, "appid");
            String secret = _HelpUtils.GetJsonArrayValue(jsonArray, "secret");
            String code = _HelpUtils.GetJsonArrayValue(jsonArray, "code");
            // String code = request.getParameter("code");
            HttpGet httpGet = new HttpGet("https://api.weixin.qq.com/sns/jscode2session?appid=" + appid + "&secret=" + secret + "&js_code=" + code + "&grant_type=authorization_code");
            //设置请求器的配置
            HttpClient httpClient = HttpClients.createDefault();
            HttpResponse res = httpClient.execute(httpGet);
            HttpEntity entity = res.getEntity();
            String result = EntityUtils.toString(entity, "UTF-8");
            // response.getWriter().append(result);
        } catch (Exception e) {

        }
        return "";
    }

//    @RequestMapping("/WeiXinSign")
@CrossOrigin
@ResponseBody
@RequestMapping(value = "/API/WeiXinSign", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    public Map<String, Object> WeiXinSign(@RequestBody JSONObject jsonParam) {
        Map<String, Object> map = new HashMap<>(1);
        try {

            String appid = jsonParam.getString("appid");
            String prepay_id = jsonParam.getString("prepay_id");
            SignInfo signInfo = new SignInfo();
            signInfo.setAppId(appid);
            long time = System.currentTimeMillis() / 1000;
            signInfo.setTimeStamp(String.valueOf(time));
            signInfo.setNonceStr(RandomStringGenerator.getRandomStringByLength(32));
            signInfo.setRepay_id("prepay_id=" + prepay_id);
            signInfo.setSignType("MD5");
            //生成签名
            String sign = Signature.getSign(signInfo);


            map.put("timeStamp", signInfo.getTimeStamp());
            map.put("nonceStr", signInfo.getNonceStr());
            map.put("package", signInfo.getRepay_id());
            map.put("signType", signInfo.getSignType());
            map.put("paySign", sign);
            return map;
        } catch (Exception e) {
            // TODO Auto-generated catch block
            map.remove("prepay_id");
            map.put("prepay_id",  e.getMessage());
            e.printStackTrace();
            L.error("-------", e);
        }
        return map;
    }

//    @RequestMapping("/WeiXinPayResult")
    @CrossOrigin
    @ResponseBody
    @RequestMapping(value = "/API/WeiXinPayResult", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    public Map<String, Object> WeiXinPayResult() {
        try {
            // TODO Auto-generated method stub
            //response.getWriter().append("Served at: ").append(request.getContextPath());

            String reqParams = StreamUtil.read(request.getInputStream());
            L.info("-------支付结果:" + reqParams);
            StringBuffer sb = new StringBuffer("<xml><return_code>SUCCESS</return_code><return_msg>OK</return_msg></xml>");
            //return sb.toString();
//            JSONObject json = new JSONObject();
//            json.put("pay_result", sb.toString());
            Map<String, Object> map = new HashMap<>(1);
            map.put("pay_result", sb.toString());
            return map;
            //return json.toString();
        } catch (Exception ex) {
        }
        return null;
    }

//    @RequestMapping("/WeixinXiadan")
@CrossOrigin
@ResponseBody
@RequestMapping(value = "/API/WeixinXiadan", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    public Map<String, Object> WeixinXiadan(@RequestBody JSONObject jsonParam) {
        Map<String, Object> map = new HashMap<>(1);
        try {

            String appid = jsonParam.getString("appid");
            String openid = jsonParam.getString("openid");
            String formcode = jsonParam.getString("formcode");
            String money = jsonParam.getString("money");
            String productDesc = jsonParam.getString("productDesc");

            int money_fen = HelpUtils.changeY2F(Double.parseDouble(money));
            //String openid = request.getParameter("openid");
            OrderInfo order = new OrderInfo();
            order.setAppid(appid);
            order.setMch_id(Configure.getMch_id()); //商户号
            order.setNonce_str(RandomStringGenerator.getRandomStringByLength(32));//随机字符串
           // String newbody=new String(productDesc.getBytes("ISO-8859-1"),"UTF-8");//以utf-8编码放入paymentPo,微信支付要求字符编码统一采用UTF-8字符编码
            order.setBody(productDesc);//商品描述s
            order.setOut_trade_no(formcode);//商户系统内部订单号
           // L.info(formcode);
            order.setTotal_fee(money_fen);//订单总金额,单位为分
            //order.setSpbill_create_ip("127.0.0.1");//调用微信支付API的机器IP
            String keyValue = env.getProperty("server.ip");
            order.setNotify_url("https://" + keyValue + "/API/WeiXinPayResult");//异步接收微信支付结果通知的回调地址,通知url必须为外网可访问的url,不能携带参数。
            order.setTrade_type("JSAPI");//交易类型 小程序取值如下:JSAPI
            order.setOpenid(openid);
            order.setSign_type("MD5");

            //生成签名
            String sign = Signature.getSign(order);
            order.setSign(sign);

            //https://api.mch.weixin.qq.com/pay/unifiedorder
            //String body  = new String(order.toString().getBytes("ISO8859-1"),"UTF-8");
            String result = HttpRequest.sendPost("https://api.mch.weixin.qq.com/pay/unifiedorder", order);
            System.out.println(result);
            L.info("---------下单返回:" + result);
            XStream xStream = new XStream();
            xStream.alias("xml", OrderReturnInfo.class);

            OrderReturnInfo returnInfo = (OrderReturnInfo) xStream.fromXML(result);
//            JSONObject json = new JSONObject();
//            json.put("prepay_id", returnInfo.getPrepay_id());//微信生成的预支付会话标识,用于后续接口调用中使用,该值有效期为2小时
//            //response.getWriter().append(json.toJSONString());
//            return json.toString();

            map.put("prepay_id", returnInfo.getPrepay_id());
            return map;
        } catch (Exception e) {
            map.remove("prepay_id");
            map.put("prepay_id",  e.getMessage());
            e.printStackTrace();
            L.error("-------", e);
        }
        return map;

    }

    @RequestMapping("/WeixinSearchOrder")
    public Map<String, Object> WeixinSearchOrder() {
        try {

        } catch (Exception ex) {
        }
        return null;
    }

    @RequestMapping("/GetTestInfo")
    public  Map<String, Object> GetTestInfo() {
        Map<String, Object> map = new HashMap<>(1);
        try {

            map.put("status","test_sucess");

        } catch (Exception ex) {
            map.put("status","test_error");
        }
        return map;
    }
}
package com.jbossjf.bootproject.common;

public class Configure {


	public static String getFile_url() {
		return file_url;
	}

	public static void setFile_url(String file_url) {
		Configure.file_url = file_url;
	}

	public static String getFile_path() {
		return file_path;
	}

	public static void setFile_path(String file_path) {
		Configure.file_path = file_path;
	}

	//上传文件
	private static  String file_url = "http://localhost:8066";
	private static  String file_path = "d:/upload/cover";

	public static String getImg_path() {
		return img_path;
	}

	public static void setImg_path(String img_path) {
		Configure.img_path = img_path;
	}

	private static  String img_path = "d:/upload/image";

   //小程序ID
   private static String appID = "5555555";//"你的小程序id";
	private static String secret = "66666";//"你的小程序的secret";
	//商户号
	private static String mch_id = "333";//"你的商户号";
	private static String key = "55555555";//"你的商户的api秘钥";
	//


	public static String getSecret() {
		return secret;
	}

	public static void setSecret(String secret) {
		Configure.secret = secret;
	}

	public static String getKey() {
		return key;
	}

	public static void setKey(String key) {
		Configure.key = key;
	}

	public static String getAppID() {
		return appID;
	}

	public static void setAppID(String appID) {
		Configure.appID = appID;
	}

	public static String getMch_id() {
		return mch_id;
	}

	public static void setMch_id(String mch_id) {
		Configure.mch_id = mch_id;
	}

}
package com.jbossjf.bootproject.common;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.thoughtworks.xstream.annotations.XStreamAlias;


/**
 * 签名
 * @author zuoliangzhu
 *
 */
public class Signature {
	private static final Logger L = LoggerFactory.getLogger(Signature.class);
	/**
     * 签名算法
     * @param o 要参与签名的数据对象
     * @return 签名
     * @throws IllegalAccessException
     */
    public static String getSign(Object o) throws IllegalAccessException {
        ArrayList<String> list = new ArrayList<String>();
        Class cls = o.getClass();
        Field[] fields = cls.getDeclaredFields();
        for (Field f : fields) {
            f.setAccessible(true);
            if (f.get(o) != null && f.get(o) != "") {
            	String name = f.getName();
            	XStreamAlias anno = f.getAnnotation(XStreamAlias.class);
            	if(anno != null)
            		name = anno.value();
                list.add(name + "=" + f.get(o) + "&");
            }
        }
        int size = list.size();
        String [] arrayToSort = list.toArray(new String[size]);
        Arrays.sort(arrayToSort, String.CASE_INSENSITIVE_ORDER);
        StringBuilder sb = new StringBuilder();
        for(int i = 0; i < size; i ++) {
            sb.append(arrayToSort[i]);
        }
        String result = sb.toString();
        result += "key=" + Configure.getKey();
        System.out.println("签名数据:"+result);
        result = MD5.MD5Encode(result).toUpperCase();
        return result;
    }

    public static String getSign(Map<String,Object> map){
        ArrayList<String> list = new ArrayList<String>();
        for(Map.Entry<String,Object> entry:map.entrySet()){
            if(entry.getValue()!=""){
                list.add(entry.getKey() + "=" + entry.getValue() + "&");
            }
        }
        int size = list.size();
        String [] arrayToSort = list.toArray(new String[size]);
        Arrays.sort(arrayToSort, String.CASE_INSENSITIVE_ORDER);
        StringBuilder sb = new StringBuilder();
        for(int i = 0; i < size; i ++) {
            sb.append(arrayToSort[i]);
        }
        String result = sb.toString();
        result += "key=" + Configure.getKey();
        //Util.log("Sign Before MD5:" + result);
        result = MD5.MD5Encode(result).toUpperCase();
        //Util.log("Sign Result:" + result);
        return result;
    }

    

}
package com.jbossjf.bootproject.common;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;

import javax.net.ssl.SSLContext;
import javax.net.ssl.X509TrustManager;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder;

public class HttpRequest {
	//连接超时时间,默认10秒
    private static final int socketTimeout = 10000;

    //传输超时时间,默认30秒
    private static final int connectTimeout = 30000;
	/**
	 * post请求
	 * @throws IOException 
	 * @throws ClientProtocolException 
	 * @throws NoSuchAlgorithmException 
	 * @throws KeyStoreException 
	 * @throws KeyManagementException 
	 * @throws UnrecoverableKeyException 
	 */
	public static String sendPost(String url, Object xmlObj) throws ClientProtocolException, IOException, UnrecoverableKeyException, KeyManagementException, KeyStoreException, NoSuchAlgorithmException {
		

        
		HttpPost httpPost = new HttpPost(url);
		//解决XStream对出现双下划线的bug
        XStream xStreamForRequestPostData = new XStream(new DomDriver("UTF-8", new XmlFriendlyNameCoder("-_", "_")));
        xStreamForRequestPostData.alias("xml", xmlObj.getClass());
        //将要提交给API的数据对象转换成XML格式数据Post给API
        String postDataXML = xStreamForRequestPostData.toXML(xmlObj);

        //得指明使用UTF-8编码,否则到API服务器XML的中文不能被成功识别
        StringEntity postEntity = new StringEntity(postDataXML, "UTF-8");
        httpPost.addHeader("Content-Type", "text/xml");
        httpPost.setEntity(postEntity);

        //设置请求器的配置
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(socketTimeout).setConnectTimeout(connectTimeout).build();
        httpPost.setConfig(requestConfig);
        
        HttpClient httpClient = HttpClients.createDefault();
        HttpResponse response = httpClient.execute(httpPost);
        HttpEntity entity = response.getEntity();
        String result = EntityUtils.toString(entity, "UTF-8");
        return result;
	}
	/**
	 * 自定义证书管理器,信任所有证书
	 * @author pc
	 *
	 */
	public static class MyX509TrustManager implements X509TrustManager {
		@Override
		public void checkClientTrusted(
				java.security.cert.X509Certificate[] arg0, String arg1)
				throws CertificateException {
			// TODO Auto-generated method stub
			
		}
		@Override
		public void checkServerTrusted(
				java.security.cert.X509Certificate[] arg0, String arg1)
				throws CertificateException {
			// TODO Auto-generated method stub
			
		}
		@Override
		public java.security.cert.X509Certificate[] getAcceptedIssuers() {
			// TODO Auto-generated method stub
			return null;
		}
      }
}
package com.jbossjf.bootproject.common;

import java.security.MessageDigest;

/**
 * User: rizenguo
 * Date: 2014/10/23
 * Time: 15:43
 */
public class MD5 {
    private final static String[] hexDigits = {"0", "1", "2", "3", "4", "5", "6", "7",
            "8", "9", "a", "b", "c", "d", "e", "f"};

    /**
     * 转换字节数组为16进制字串
     * @param b 字节数组
     * @return 16进制字串
     */
    public static String byteArrayToHexString(byte[] b) {
        StringBuilder resultSb = new StringBuilder();
        for (byte aB : b) {
            resultSb.append(byteToHexString(aB));
        }
        return resultSb.toString();
    }

    /**
     * 转换byte到16进制
     * @param b 要转换的byte
     * @return 16进制格式
     */
    private static String byteToHexString(byte b) {
        int n = b;
        if (n < 0) {
            n = 256 + n;
        }
        int d1 = n / 16;
        int d2 = n % 16;
        return hexDigits[d1] + hexDigits[d2];
    }

    /**
     * MD5编码
     * @param origin 原始字符串
     * @return 经过MD5加密之后的结果
     */
    public static String MD5Encode(String origin) {
        String resultString = null;
        try {
            resultString = origin;
            MessageDigest md = MessageDigest.getInstance("MD5");
            resultString = byteArrayToHexString(md.digest(resultString.getBytes()));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return resultString;
    }

}

package com.jbossjf.bootproject.common;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;

public class StreamUtil {
	public static String read(InputStream is){
		try {
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			int len = 0;
			byte[] buffer = new byte[512];
			while((len = is.read(buffer)) != -1){
				baos.write(buffer, 0, len);
			}
			return new String(baos.toByteArray(), 0, baos.size(), "utf-8");
		}catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return "";
	}
}
package com.jbossjf.bootproject.common;

import java.util.Random;

/**
 * 随机字符串生成
 * @author zuoliangzhu
 *
 */
public class RandomStringGenerator {
	/**
     * 获取一定长度的随机字符串
     * @param length 指定字符串长度
     * @return 一定长度的字符串
     */
    public static String getRandomStringByLength(int length) {
        String base = "abcdefghijklmnopqrstuvwxyz0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值