stripe国际支付(对接支付宝、微信)

前言:stripe国际支付现在网上资料很少,且不支持中国,所以如果要用需要去支持的国家注册商户,官网的java demo是用的spark框架,我这里用的spring,验签需要手动验签,且不能用官网的方法

正文:

支付宝文档地址:https://stripe.com/docs/sources/alipay

微信支付文档地址:https://stripe.com/docs/sources/wechat-pay

支付宝和微信的流程差不多一样。

做了个简单的时序图

关于配置:

回调地址配置,可以每个触发事件都配置不一样的url,也可以都配置一个,我只配置了一个

获得source时候发送请求用到的公匙:

代码:

<!-- stripe支付官方包 -->
<dependency><groupId>com.stripe</groupId><artifactId>stripe-java</artifactId><version>7.26.0</version>
</dependency>

其实只有三个接口:

1.给前端准备数据

2.授权完回调地址

3.回调接口

回调接口:

常量类:

service:

package com.otcbi.pay.service.impl;import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.gson.JsonSyntaxException;
import com.otcbi.coin.common.exception.ApiException;
import com.otcbi.coin.common.exception.ApiResponMessage;
import com.otcbi.constat.Consts;
import com.otcbi.pay.entity.StripeOrder;
import com.otcbi.pay.service.IGoodsOnlineService;
import com.otcbi.pay.service.IStripeOrderService;
import com.otcbi.pay.service.IStripeWebhookMessageService;
import com.otcbi.shop.dto.StripeCreateSourceDTO;
import com.otcbi.shop.entity.Orders;
import com.otcbi.shop.service.IOrdersService;
import com.stripe.Stripe;
import com.stripe.exception.SignatureVerificationException;
import com.stripe.model.Charge;
import com.stripe.model.Event;
import com.stripe.model.EventData;
import com.stripe.net.Webhook;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;@Service
public class IGoodsOnlineServiceImpl implements IGoodsOnlineService {private static final Logger logger = LoggerFactory.getLogger(IGoodsOnlineServiceImpl.class);@Value("${stripe.homeUrl}")private String homeUrl;@Value("${stripe.apiKey}")String stripeApiKey;@Value("${stripe.webhookSecret}")String stripeWebhookSecret;@Autowiredprivate IOrdersService iOrdersService;@Autowiredprivate IStripeOrderService iStripeOrderService;@Autowiredprivate IStripeWebhookMessageService iStripeWebhookMessageService;public StripeCreateSourceDTO createSource(Long ordersId) throws Exception {Orders orders = iOrdersService.getById(ordersId);if (orders == null) {throw new ApiException(ApiResponMessage.SHOP_ORDERS_EXIST, null);} else if (orders.getPayState() == 2) {throw new ApiException(ApiResponMessage.ORDERS_ALREADY_FINISHED, null);}StripeCreateSourceDTO source = new StripeCreateSourceDTO();source.setUserId(orders.getUserId());if (orders.getPayType() == 1) {source.setType("alipay");} else if (orders.getPayType() == 2) {source.setType("wechat");}source.setCurrency(orders.getCoin());source.setOrderNum(orders.getOrderNum());source.setReturnUrl(homeUrl + "/stripe/createSourceRetuenBack?orderNum=" + orders.getOrderNum());QueryWrapper<StripeOrder> wrapper = new QueryWrapper<>();wrapper.eq("is_deleted", "N");wrapper.eq("order_num", orders.getOrderNum());wrapper.eq("is_cancel", 0);StripeOrder stripeOrder = iStripeOrderService.getOne(wrapper);if (stripeOrder == null) {//创建stripe订单stripeOrder = new StripeOrder();stripeOrder.setIsDeleted("N");stripeOrder.setCreateTime(LocalDateTime.now());stripeOrder.setOrderNum(orders.getOrderNum());stripeOrder.setStatus(Consts.PAY_STRIPE_STATUS_PENDING);Integer realAmount = Integer.valueOf(new BigDecimal(orders.getActualPrice().toString()).multiply(new BigDecimal("100")).setScale(0, BigDecimal.ROUND_DOWN).toString());Integer amount = Integer.valueOf(realAmount.toString());source.setAmount(amount);stripeOrder.setAmount(realAmount);stripeOrder.setType(source.getType());stripeOrder.setUserId(orders.getUserId());stripeOrder.setCurrency(orders.getCoin());iStripeOrderService.save(stripeOrder);return source;} else {String status = stripeOrder.getStatus();if (Consts.PAY_STRIPE_STATUS_SUCCEEDED.equals(status)) {//已经完成throw new ApiException(ApiResponMessage.ORDERS_ALREADY_FINISHED, null);} else if (Consts.PAY_STRIPE_STATUS_CANCELED.equals(status) || Consts.PAY_STRIPE_STATUS_INSUFFICIENT_fUNDS.equals(status)|| Consts.PAY_STRIPE_STATUS_INVALID_AMOUNT.equals(status) || Consts.PAY_STRIPE_STATUS_CHARGE_ERROR.equals(status)) {//已经失效,删除原来订单,重新创建订单stripeOrder.setIsCancel(1);stripeOrder.setModifyTime(LocalDateTime.now());iStripeOrderService.updateById(stripeOrder);StripeOrder stripeOrderNew = new StripeOrder();stripeOrderNew.setIsDeleted("N");stripeOrderNew.setCreateTime(LocalDateTime.now());stripeOrderNew.setOrderNum(orders.getOrderNum());stripeOrderNew.setStatus(Consts.PAY_STRIPE_STATUS_PENDING);Integer realAmount = Integer.valueOf(new BigDecimal(orders.getActualPrice().toString()).multiply(new BigDecimal("100")).setScale(0, BigDecimal.ROUND_DOWN).toString());Integer amount = Integer.valueOf(realAmount.toString());source.setAmount(amount);stripeOrderNew.setAmount(realAmount);stripeOrderNew.setType(source.getType());stripeOrder.setUserId(orders.getUserId());stripeOrder.setCurrency(orders.getCoin());iStripeOrderService.save(stripeOrderNew);return source;} else {if (Consts.PAY_STRIPE_STATUS_PENDING.equals(status)) {//还未授权Integer amount = Integer.valueOf(new BigDecimal(stripeOrder.getAmount().toString()).setScale(0, BigDecimal.ROUND_DOWN).toString());source.setAmount(amount);return source;} else if (Consts.PAY_STRIPE_STATUS_CHARGEABLE.equals(status)) {//已经授权,按理来说这个时候已经完成了订单throw new ApiException(ApiResponMessage.SHOP_ORDERS_PLAYING_ERROR, null);} else if (Consts.PAY_STRIPE_STATUS_FAILED.equals(status)) {//拒绝授权支付,重新要求授权Integer amount = Integer.valueOf(new BigDecimal(stripeOrder.getAmount().toString()).setScale(0, BigDecimal.ROUND_DOWN).toString());source.setAmount(amount);return source;} else {throw new ApiException(ApiResponMessage.SHOP_GOODS_WEIXIN_PAY_ERROR, null);}}}}/*** 如果客户的支付宝账户被非法使用,支付宝和Stripe会在内部处理此问题。在支付宝的情况下,* 只有当客户对所提供的商品或服务有投诉时,付款才会有争议。* 如果发生争议,dispute.created则会发送webhook事件,Stripe会从您的Stripe余额中扣除争议金额。* <p>* 一个chargeable单一使用支付宝源必须在6小时内变得收费chargeable。如果不是,则其状态将自动转换为canceled* 您的集成并收到source.canceledwebhook事件。取消收费来源后,客户的授权支付宝付款将自动退还 -* 不会将任何款项转入您的帐户。因此,请确保您的订单已取消,并在收到source.canceled活动时通知客户。* 此外,pending如果不用于授权付款,则在一小时后取消资源,确保所有资源最终从pending状态转移到canceled状态(如果不使用)。** @param request* @param response* @throws Exception*/@Transactionalpublic synchronized void stripeCallBack(HttpServletRequest request, HttpServletResponse response) throws Exception {logger.info("============进入webhook回调=================");//验签Event event = attestation(request, response);if (event == null) {return;}/*不验签获得数据Event event = ApiResource.GSON.fromJson(request.getReader(), Event.class);*/String message = event.toJson();logger.info("收到内容为:" + message);String stripeType = event.getType();//把信息记录到表iStripeWebhookMessageService.saveWebHootMssage(event, message, stripeType);if (stripeType.equals("source." + Consts.PAY_STRIPE_STATUS_CHARGEABLE)) {//用户授权确认callBackPending(event, response);} else if (stripeType.equals("source." + Consts.PAY_STRIPE_STATUS_FAILED)) {//用户拒绝授权callBackFailed(event, response);} else if (stripeType.equals("source." + Consts.PAY_STRIPE_STATUS_CANCELED)) {//过期callBackCanceled(event, response);} else if (stripeType.equals("charge." + Consts.PAY_STRIPE_STATUS_SUCCEEDED)) {//stripe收款成功通知callBackSuccess(event, response);} else if (stripeType.equals("charge.dispute." + Consts.PAY_STRIPE_STATUS_CREATED)) {//客户投诉退款callBackCreated(event, response);} else {logger.error("获得未知状态" + stripeType);response.setStatus(500);logger.info("============webhook回调结束=================");return;}response.setStatus(200);logger.info("============webhook回调结束=================");}public Event attestation(HttpServletRequest request, HttpServletResponse response) throws Exception {String endpointSecret = stripeWebhookSecret;InputStream inputStream = request.getInputStream();byte[] bytes = IOUtils.toByteArray(inputStream);String payload = new String(bytes, "UTF-8");String sigHeader = request.getHeader("Stripe-Signature");Event event = null;try {event = Webhook.constructEvent(payload, sigHeader, endpointSecret);logger.info("验签成功");response.setStatus(200);return event;} catch (JsonSyntaxException e) {logger.error("验签失败");response.setStatus(400);} catch (SignatureVerificationException e) {logger.error("验签失败");e.printStackTrace();response.setStatus(400);}logger.info("============webhook回调结束=================");return null;}public void callBackPending(Event event, HttpServletResponse response) throws Exception {EventData eventData = event.getData();JSONObject json = JSONObject.parseObject(eventData.getObject().toJson());String client_secret = json.getString("client_secret");String orderNum = json.getString("statement_descriptor");String stripe_id = json.getString("id");String type = json.getString("type");String amount = json.getString("amount");String currency = json.getString("currency");String userId = json.getJSONObject("owner").getString("name");QueryWrapper<StripeOrder> wrapper = new QueryWrapper<>();wrapper.eq("is_deleted", "N");wrapper.eq("order_num", orderNum);wrapper.eq("is_cancel", 0);wrapper.eq("type", type);wrapper.eq("user_id", userId);StripeOrder stripeOrder = iStripeOrderService.getOne(wrapper);if (stripeOrder == null) {//订单不存在logger.error("Stripe收到不存在的订单回调" + orderNum);response.setStatus(500);} else {if (!stripeOrder.getStatus().equals(Consts.PAY_STRIPE_STATUS_PENDING)) {logger.error("Stripe收到违法订单" + orderNum);}if (!amount.equals(stripeOrder.getAmount().toString())) {logger.error("Stripe收到金额对不上的订单回调" + orderNum);response.setStatus(500);}//客户已经完成授权stripeOrder.setStripeId(stripe_id);stripeOrder.setStatus(Consts.PAY_STRIPE_STATUS_CHARGEABLE);stripeOrder.setClientSecret(client_secret);stripeOrder.setModifyTime(LocalDateTime.now());iStripeOrderService.updateById(stripeOrder);logger.info("===================" + orderNum + "订单授权成功=============");//创建支付订单try {createCharge(stripeOrder, Integer.valueOf(amount), currency, stripe_id, orderNum);} catch (Exception e) {e.printStackTrace();logger.error(orderNum + "stripe创建收费订单失败");}}}/*** 拒绝授权** @param event* @param response* @throws Exception*/public void callBackFailed(Event event, HttpServletResponse response) throws Exception {EventData eventData = event.getData();JSONObject json = JSONObject.parseObject(eventData.getObject().toJson());String client_secret = json.getString("client_secret");String orderNum = json.getString("statement_descriptor");String stripe_id = json.getString("id");String type = json.getString("type");String amount = json.getString("amount");String currency = json.getString("currency");String userId = json.getJSONObject("owner").getString("name");QueryWrapper<StripeOrder> wrapper = new QueryWrapper<>();wrapper.eq("is_deleted", "N");wrapper.eq("order_num", orderNum);wrapper.eq("is_cancel", 0);wrapper.eq("type", type);wrapper.eq("user_id", userId);StripeOrder stripeOrder = iStripeOrderService.getOne(wrapper);if (stripeOrder == null) {//订单不存在logger.error("Stripe收到不存在的订单回调" + orderNum);response.setStatus(500);} else {if (!stripeOrder.getStatus().equals(Consts.PAY_STRIPE_STATUS_PENDING)) {logger.error("Stripe收到违法订单" + orderNum);}if (!amount.equals(stripeOrder.getAmount().toString())) {logger.error("Stripe收到金额对不上的订单回调" + orderNum);response.setStatus(500);}//客户不授权删除订单stripeOrder.setStatus(Consts.PAY_STRIPE_STATUS_FAILED);stripeOrder.setClientSecret(client_secret);stripeOrder.setModifyTime(LocalDateTime.now());stripeOrder.setIsCancel(1);stripeOrder.setStripeId(stripe_id);iStripeOrderService.updateById(stripeOrder);logger.info("===================" + orderNum + "订单拒绝授权处理成功=============");}}/*** 过期订单** @param event* @param response* @throws Exception*/public void callBackCanceled(Event event, HttpServletResponse response) throws Exception {EventData eventData = event.getData();JSONObject json = JSONObject.parseObject(eventData.getObject().toJson());String client_secret = json.getString("client_secret");String orderNum = json.getString("statement_descriptor");String stripe_id = json.getString("id");String type = json.getString("type");String amount = json.getString("amount");String currency = json.getString("currency");String userId = json.getJSONObject("owner").getString("name");QueryWrapper<StripeOrder> wrapper = new QueryWrapper<>();wrapper.eq("is_deleted", "N");wrapper.eq("order_num", orderNum);wrapper.eq("is_cancel", 0);wrapper.eq("type", type);wrapper.eq("user_id", userId);wrapper.eq("stripe_id", stripe_id);StripeOrder stripeOrder = iStripeOrderService.getOne(wrapper);if (stripeOrder == null) {//订单不存在logger.error("Stripe收到不存在的订单回调" + orderNum);response.setStatus(500);} else {if (!stripeOrder.getStatus().equals(Consts.PAY_STRIPE_STATUS_PENDING)) {logger.error("Stripe收到违法订单" + orderNum);}if (!amount.equals(stripeOrder.getAmount().toString())) {logger.error("Stripe收到金额对不上的订单回调" + orderNum);response.setStatus(500);}//订单过期删除订单stripeOrder.setStatus(Consts.PAY_STRIPE_STATUS_CANCELED);stripeOrder.setClientSecret(client_secret);stripeOrder.setModifyTime(LocalDateTime.now());stripeOrder.setIsCancel(1);iStripeOrderService.updateById(stripeOrder);logger.info("===================" + orderNum + "订单过期处理成功=============");}}public void callBackCreated(Event event, HttpServletResponse response) throws Exception {EventData eventData = event.getData();//待写}public void callBackSuccess(Event event, HttpServletResponse response) throws Exception {EventData eventData = event.getData();JSONObject json = JSONObject.parseObject(eventData.getObject().toJson());String orderNum = json.getJSONObject("source").getString("statement_descriptor");String stripe_id = json.getJSONObject("source").getString("id");String type = json.getJSONObject("source").getString("type");String amount = json.getJSONObject("source").getString("amount");String userId = json.getJSONObject("source").getJSONObject("owner").getString("name");String payId = json.getString("id");QueryWrapper<StripeOrder> wrapper = new QueryWrapper<>();wrapper.eq("is_deleted", "N");wrapper.eq("order_num", orderNum);wrapper.eq("is_cancel", 0);wrapper.eq("type", type);wrapper.eq("user_id", userId);wrapper.eq("stripe_id", stripe_id);StripeOrder stripeOrder = iStripeOrderService.getOne(wrapper);if (stripeOrder == null) {//订单不存在logger.error("Stripe收到不存在的订单回调" + orderNum);response.setStatus(500);} else {if (!stripeOrder.getStatus().equals(Consts.PAY_STRIPE_STATUS_CHARGEABLE)) {logger.error("Stripe收到违法订单" + orderNum);}if (!amount.equals(stripeOrder.getAmount().toString())) {logger.error("Stripe收到金额对不上的订单回调" + orderNum);response.setStatus(500);}//客户付款成功stripeOrder.setStatus(Consts.PAY_STRIPE_STATUS_SUCCEEDED);stripeOrder.setModifyTime(LocalDateTime.now());stripeOrder.setPayId(payId);iStripeOrderService.updateById(stripeOrder);//更改订单状态QueryWrapper<Orders> orderWrapper = new QueryWrapper<>();orderWrapper.eq("order_num", orderNum);orderWrapper.eq("is_deleted", "N");Orders orders = iOrdersService.getOne(orderWrapper);orders.setModifyTime(LocalDateTime.now());orders.setPayState(2);iOrdersService.updateById(orders);logger.info("===================" + orderNum + "订单付款成功=============");}}/*** 创建收费订单** @param amount* @param currency* @param stripeId* @throws Exception 支付宝付款的费用创建可能会返回以下任何错误:*                   insufficient_funds    支付宝账户资金不足,无法完成购买。客户应为其帐户注资并重试,或使用其他付款方式。*                   invalid_amount    如果收费金额大于支付宝支持的费用,则会发生这种情况。*/public void createCharge(StripeOrder stripeOrder, Integer amount, String currency, String stripeId, String orderNum) throws Exception {Stripe.apiKey = stripeApiKey;Map<String, Object> chargeParams = new HashMap<String, Object>();chargeParams.put("amount", amount);chargeParams.put("currency", currency);chargeParams.put("source", stripeId);chargeParams.put("description", orderNum + " completion of payment");Charge charge = Charge.create(chargeParams);String errorMsg = charge.getFailureMessage();if (StringUtils.isEmpty(errorMsg)) {logger.info(orderNum + "订单请求支付成功");} else {if (errorMsg.equals("insufficient_funds")) {logger.error(orderNum + "订单用户支付宝余额不足");stripeOrder.setStatus(Consts.PAY_STRIPE_STATUS_INSUFFICIENT_fUNDS);stripeOrder.setModifyTime(LocalDateTime.now());} else if (errorMsg.equals("invalid_amount")) {logger.error(orderNum + "订单收费金额大于支付宝支持的费用");stripeOrder.setStatus(Consts.PAY_STRIPE_STATUS_INVALID_AMOUNT);stripeOrder.setModifyTime(LocalDateTime.now());} else {logger.error(orderNum + errorMsg);stripeOrder.setStatus(Consts.PAY_STRIPE_STATUS_CHARGE_ERROR);stripeOrder.setModifyTime(LocalDateTime.now());}iStripeOrderService.updateById(stripeOrder);}logger.info("===================" + orderNum + "订单申请扣费成功=============");}}

h5页面:

createSource:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><!--官方js--><script src="https://js.stripe.com/v3/"></script><script type="text/javascript" src="/jquery.min.js"></script><script type="text/javascript">$(document).ready(function () {var amount = $("#amount").val();var returnUrl = $("#returnUrl").val();var currency = $("#currency").val();var type = $("#type").val();var userId = $("#userId").val();var orderNum = $("#orderNum").val();var stripe = Stripe($('#stripe').val());stripe.createSource({type: type,amount: amount,currency: currency,statement_descriptor : orderNum,owner: {name: userId,},redirect: {return_url: returnUrl},}).then(function (result) {// handle result.error or result.sourceif (result.source != null) {if(result.source.type == "wechat"){window.location.href=result.source.wechat.qr_code_url;}else {window.location.href=result.source.redirect.url;}} else {alert(result.error.message);}});});</script>
</head></head>
<body>
<h1>跳转授权页面中。。。。</h1>
<input type="hidden" id="stripe" th:value="${stripe}">
<input type="hidden"  id="type" th:value="${dto.type}">
<input type="hidden"  id="amount" th:value="${dto.amount}">
<input type="hidden"  id="returnUrl" th:value="${dto.returnUrl}">
<input type="hidden"  id="currency" th:value="${dto.currency}">
<input type="hidden"  id="userId" th:value="${dto.userId}">
<input type="hidden"  id="orderNum" th:value="${dto.orderNum}">
</body>
</html>

temp.html:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script type="text/javascript" src="/jquery.min.js"></script>
</head>
<body><h1>您的订单授权已受理,正在等待第三方处理,请稍后查询订单状态</h1>
</body>
</html>

 

这里遇到一个特别坑的地方:就是验签的时候官网给的demo是:

用到spark,以为引入spark pom就行了,结果一直不行,后来联系他们客服,然后给了我个irc的地址让我跟他们技术人员谈,聊了好久才知道,原来他们用的是spark框架不能和spring拼凑使用,聊天内容:

聊天知道了几个重要内容:

如果不响应会持续回调72小时,时间递增的回调

验签获取payload 的获取关键代码:

InputStream inputStream = request.getInputStream();
byte[] bytes = IOUtils.toByteArray(inputStream);
String payload = new String(bytes, "UTF-8");

如果有什么不懂欢迎留言!

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/62482.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

再度盈利,搜狐稳了?

2016年在宣布要用3年时间回归互联网舞台中心之后&#xff0c;很长一段时间内张朝阳积极活跃在各种社交媒体上&#xff0c;完全是一派“积极出山”的姿态。而后畅游从美股退市&#xff0c;搜狗“卖身”腾讯&#xff0c;一系列的收缩动作又似乎是在逐渐远离喧嚣。 而在最近三年&a…

宝宝入托,爸妈要避开这5种心态

孩子入托&#xff0c;父母也要做好心理准备&#xff0c;尤其需要避免以下5种常见的、不良心理状态&#xff0c;否则会加重孩子入托的困难度。 01.“生离死别式”的入托状态 即每次送孩子入园&#xff0c;就像一场生离死别。宝宝屋里哭&#xff0c;家长屋外哭&#xff0c;最后多…

小孩从小就学习编程,真的有必要吗?

现今&#xff0c;许多面向儿童的计算机教程和编程语言十分风行&#xff0c;那么是否人人都应该从小学计算机呢&#xff1f; 美国前总统奥巴马曾表示&#xff0c;应该“向每个学生提供动手式的计算机科学和数学课程&#xff0c;从一开始就让他们为将来的工作做好准备。”不久&am…

你喜欢读书,还是听书?

前段时间在我的星球里做了一个小调研&#xff0c;我看一些知识付费的课程素材&#xff0c;我发现我的阅读速度&#xff0c;是播放语音效率的5倍以上&#xff0c;十几分钟的语音课程&#xff0c;我看文字可能两分钟就看完了。但我知道&#xff0c;很多人还是更喜欢聆听。 实际上…

小孩厌学,与其说教,不如和他写个游戏

表弟又闹着不去幼儿园了,我得想个办法让他体会到学习的快乐和意义…… 带娃真难 玩了一个周末,玩舒服了,周一起床后,一听要去学校,就不干了,死活不去,对我们各种撒(威)泼(逼)打(利)滚(诱),实在招架不住,只能妥协了,虽然我可以扛起他,塞进校车里,但受过良好…

20本父母必读的亲子教育书籍

作者注&#xff1a;有位好朋友成为母亲没多久&#xff0c;向我提出一个要求&#xff0c;说不知道怎么教孩子&#xff0c;看我是否能帮助推荐一些这方面的书籍。经过一段时间的搜索和整理&#xff0c;给她整理出一套书单&#xff0c;朋友看了后&#xff0c;说受益匪浅。现在她的…

读懂婴幼儿心理学,不要随便责怪孩子

读懂婴幼儿心理学&#xff0c;不要随便责怪孩子 一、不知道孩子在0-6岁时存在各种敏感期&#xff0c;把孩子在敏感期的表现当成不乖的行为斥责孩子&#xff0c;违背了孩子的天性&#xff0c;造成他的痛苦&#xff0c;留下心理隐患。 孩子在0-6岁时存在各种各样的敏感期&a…

和孩子读书学习的一点心得

这是学习笔记的第 2386篇文章 最近带着孩子做了一些实验和游戏&#xff0c;也总结了几个经验和技巧。 #1 小步迭代&#xff0c;做电路实验 最近带着孩子做电路实验&#xff0c;和上一次玩电路实验已经隔了好一段时间&#xff0c; 孩子应该都基本忘了那种感觉了&#xff0c;所以…

读书会招募 | 一起来读《蛤蟆先生去看心理医生》吧

Hello&#xff0c;大家好&#xff0c; 欢迎来到壹脑云读书圈&#xff0c;我是瘦瘦~ 随着国家经济社会的快速发展&#xff0c;人们的心理问题逐渐增多&#xff0c;新冠疫情也对人们的心理健康带来了或多或少的消极影响。 在此背景下&#xff0c;面对心理咨询&#xff0c;一方…

请告诉孩子:努力读书,是为将来拥有更多选择的权利,而不是被迫谋生

请告诉孩子&#xff1a;努力读书&#xff0c;是为将来拥有更多选择的权利&#xff0c;而不是被迫谋生 01 现在的孩子津津乐道于几个文化不高、但事业有成的名人&#xff0c;用于堵住家长苦口婆心的嘴。 然而事实是&#xff0c;这样的人只是少数&#xff0c;大多数不爱学习的…

经常看书的人和不看书的人有什么区别?

只要能做到高效看经典书籍&#xff0c;对个人提升一定是飞快的&#xff01; 其实能坚持每天看书两小书&#xff08;武侠言情之类的杂书除外&#xff09;&#xff0c;已经超过99%的人了。 99%并不夸张&#xff0c;甚至会更多&#xff0c;我们中的很多人除了读书时期会看书&…

外贸大环境下soho人策略

前阵子也跟一个工厂在聊&#xff0c;现在普遍毛利率只有5%-6%&#xff0c;根本不敢涨价&#xff0c;能不降价就不错了&#xff08;汇率在涨&#xff0c;所以有的客户还会要求降价&#xff09;。 卷是一定的。而且&#xff0c;各位如果有了解过拼多多的TEMU业务的&#xff0c;应…

传统外贸B2B企业如何转型为跨境电商B2B

国内传统的外贸B2B产业深度仰赖出口商、代理商、参展等方式&#xff0c;但因为新冠疫情使得传统外贸的秩序被打乱&#xff0c;这对外贸企业有着不小的冲击。因此在政策拉动、市场需求驱动及数字技术进步等多重力量共同作用下&#xff0c;许多传统外贸企业纷纷开始转型跨境电商B…

国内出海企业常见的跨境网络问题分析及解决方案

经济全球化趋势发展得如火如荼&#xff0c;越来越多的中国企业走出国门&#xff0c;兴起包括跨境电商、虚拟商品、游戏出海等新贸易形式。 但在业务开拓过程中&#xff0c;由于远距离传输的特殊性&#xff0c;出海企业经常面临网络传输慢、不稳定、延迟、掉线等网络问题&#x…

B2B外贸行业如何利用TikTok打开海外销售渠道-跨境知道

过去数年&#xff0c;中国供应链能力不断提升&#xff0c;生产物资过剩&#xff0c;移动互联网红利见顶&#xff0c;加上政策因素&#xff0c;越来越多的中国企业开始出海寻求增长。根据海关总署发布的数据显示&#xff1a;2021年&#xff0c;我国货物贸易进出口总值39.1万亿元…

目前我国外贸企业生存现状如何?

今天&#xff0c;最新的进出口贸易数据发布。 海关总署9日公布的数据显示&#xff0c;今年前4个月&#xff0c;我国进出口总值12.58万亿元&#xff0c;同比增长7.9%。虽然整体增速有所回落&#xff0c;但完全在可控范围内。 但是增速下的外贸企业就不那么好做了&#xff0c;很多…

外贸管理软件的发展现状及趋势分析

目前市场上的外贸管理软件大致分为两类公司&#xff1a;一是侧重于外贸业务流程管控为主&#xff0c;另一类是侧重于前期客户管理为主&#xff1b;接下来我们就主要对这两类公司的现状和未来的发展趋势做下分析&#xff0c;希望对于进行软件选型的企业有所帮助&#xff01; 第一…

GESP一级、二级、三级、四级 样题 真题 解析

GESP的前世今生 GESP的前世今生_哔哩哔哩_bilibili GESP考试基础知识串讲01 GESP考试基础知识串讲01_哔哩哔哩_bilibili 中国计算机学会CCF编程能力等级认证GESP 编程C一级之一题② 中国计算机学会CCF编程能力等级认证GESP 编程C一级之一题②_哔哩哔哩_bilibili 中国计算机学会…

腾讯公司市值4635亿美元,重回全球上市公司市值榜第八名

美国时间1月11日&#xff0c;大型科技股多数上涨&#xff0c;亚马逊涨近6%&#xff0c;苹果、谷歌、特斯拉涨幅均超过3%。热门中概股涨跌不一&#xff0c;爱奇艺涨超6%&#xff0c;腾讯控股市值挺进全球前10名。 全球上市公司市值排行网CompaniesMarketCap&#xff08;公司市值…

清华工科博士答辩PPT(转载)

答辩前吸一下欧气&#xff08;转自B站视频&#xff09;参考链接 大佬