Alipay(支付寶支付) 如何實(shí)現(xiàn)一個項(xiàng)目配置多個商戶信息付款給對應(yīng)商戶

如何實(shí)現(xiàn)一個項(xiàng)目配置多個商戶信息付款給對應(yīng)商戶

最近在對接支付寶支付時(shí),遇到了一個問題

用戶在付款時(shí)臣樱,需要直接付款到指定支付寶賬戶。

這個需求也無可厚非,就像我們公司有四個分公司框沟,分別在北京藏古、上海等地,如果錢只能到總公司的賬戶上忍燥,那在財(cái)務(wù)結(jié)算的時(shí)候就很麻煩拧晕。

簡單說一下問題背景:

公司準(zhǔn)備上線一個商城應(yīng)用,有分公司和服務(wù)商的概念梅垄,意思就是收錢的不是一個人厂捞。

前一陣子,螞蟻金服投了一大筆錢队丝,也算是達(dá)成了合作靡馁,所以在第三方支付中首選了支付寶,場景是手機(jī)網(wǎng)站支付机久,問題就在這出現(xiàn)了臭墨。目前支付寶只在當(dāng)面付中支持配置多個收款賬戶,也是在社區(qū)里逛了一陣子才知道這個信息的膘盖。

[圖片上傳失敗...(image-88cfb5-1540283092156)]
[圖片上傳失敗...(image-7f4e27-1540283092156)]
螞蟻金服開發(fā)者社區(qū)原貼:如何實(shí)現(xiàn)一個項(xiàng)目配置多個商戶信息付款給對應(yīng)商戶

上面的帖子明確說明了目前實(shí)現(xiàn)的兩種方式胧弛,很明顯方案二看起來比較優(yōu)雅,也比較好實(shí)現(xiàn)侠畔,但是很抱歉结缚,手機(jī)網(wǎng)站支付不支持方案二。

ps:判斷是否支持方案二的方法就是去看它的文檔软棺,如果請求參數(shù)中有app_auth_token這個參數(shù)就是支持方案二的红竭。

為了證實(shí)這個蛋疼的消息,我又專門發(fā)了一個帖子確認(rèn)了一遍

手機(jī)網(wǎng)站支付遇到了一些問題

管理員明確的回復(fù)了我喘落,只能用方案一德崭,并且要申請N個應(yīng)用,并全部上線揖盘。

Google了一下眉厨,沒搜到用這種方式實(shí)現(xiàn)的代碼,只能自己寫了兽狭。憾股。

支付寶最終是根據(jù)請求過來的appid來判斷哪一個商戶收款(也就是請求是誰的appid就收款到誰的賬號下)

所以我申請了四個應(yīng)用。箕慧。服球。。

先定一個接口;

public interface AlipayClientConfig {
  /**
   * 網(wǎng)關(guān).
   */
  String getGatewayUrl();
  /**
   * appid.
   */
  String getAppId();
  /**
   * 私鑰.
   */
  String getAppPrivateKey();
  /**
   * 格式 默認(rèn)json.
   */
  String getFormat();
  /**
   * 編碼 默認(rèn)utf-8.
   */
  String getCharset();
  /**
   * 支付寶公鑰.
   */
  String getAlipayPublicKey();
  /**
   * 簽名方式.
   */
  String getSignType();
}

在定義一個抽象類實(shí)現(xiàn)接口;

@Getter
@Setter
public class AlipayAbstractClientConfig implements AlipayClientConfig {

  /**
   * 網(wǎng)關(guān).
   */
  private String gatewayUrl;
  /**
   * appid.
   */
  private String appId;
  /**
   * 私鑰.
   */
  private String appPrivateKey;
  /**
   * 格式 默認(rèn)json.
   */
  private String format;
  /**
   * 編碼 默認(rèn)utf-8.
   */
  private String charset;
  /**
   * 支付寶公鑰.
   */
  private String alipayPublicKey;
  /**
   * 簽名方式.
   */
  private String signType;
}

然后是四個配置文件繼承抽象類;

@Configuration(AlipayConstant.BEIJING_CLIENT)
@ConfigurationProperties(prefix = "alipay.apenapi.beijing")
@Getter
@Setter
public class AlipayBeiJingClientConfig extends AlipayAbstractClientConfig {

}

@Configuration(AlipayConstant.NANJING_CLIENT)
@ConfigurationProperties(prefix = "alipay.apenapi.nanjing")
@Getter
@Setter
public class AlipayNanJingClientConfig extends AlipayAbstractClientConfig {

}

@Configuration(AlipayConstant.SHANGHAI_CLIENT)
@ConfigurationProperties(prefix = "alipay.apenapi.shanghai")
@Getter
@Setter
public class AlipayShangHaiClientConfig extends AlipayAbstractClientConfig {

}

@Configuration(AlipayConstant.TIANJIN_CLIENT)
@ConfigurationProperties(prefix = "alipay.apenapi.tianjin")
@Getter
@Setter
public class AlipayTianJinClientConfig extends AlipayAbstractClientConfig {

}

注解的常量信息颠焦;

public interface AlipayConstant {

  String BEIJING_CLIENT = "BJ";
 
  String TIANJIN_CLIENT = "TJ";
  
  String NANJING_CLIENT = "NJ";
 
  String SHANGHAI_CLIENT = "SH";
}

再貼一下配置文件信息斩熊;

alipay:
  apenapi:
    tianjin:
      gateway_url: https://openapi.alipay.com/gateway.do
      app_id: 2018*********
      app_private_key: KubiKtPbIoMLITLRMKTu9MwIwE8lC9Grg5
                       6c/00rsypY/b8SQh8ydYsEPt098JYAEhS6HvLQNz6W5XvCZNeAcv307kj3RYql2W
                       Xntkh9Rr0s/cEc1WnHmBeUF3
      alipay_public_key: MIIBIjANBgkqhkistdzwIDAQAB
      format: json
      charset: utf-8
      sign_type: RSA2
    beijing:
      gateway_url: https://openapi.alipay.com/gateway.do
      app_id: 2018**********
      app_private_key: JTj9Lz6G4W3RMO8QCCK8XYWdkEH5H5I
      alipay_public_key: MIIBIjANBgB
      format: json
      charset: utf-8
      sign_type: RSA2
    shanghai:
      gateway_url: https://openapi.alipay.com/gateway.do
      app_id: 2018********
      app_private_key: MIIEvAIBADANBgcpUyx/WxcdhuAYmF3Di
      alipay_public_key: MIIBIjANBgkqhkiG9w0
      format: json
      charset: utf-8
      sign_type: RSA2
    nanjing:
      gateway_url: https://openapi.alipay.com/gateway.do
      app_id: 20181********
      app_private_key: MIIEvgIBA
      alipay_public_key: MIIBIjANBgk
      format: json
      charset: utf-8
      sign_type: RSA2

在service層調(diào)用時(shí),只要動態(tài)的獲取不同的配置文件伐庭,即可初始化不同的AlipayClient粉渠,向支付寶發(fā)起請求分冈;

@Service
@Slf4j
@Transactional(readOnly = true)
public class AlipayServiceImpl implements AlipayService {

  @Autowired
  private AlipayDetailConfig alipayDetailConfig;

  @Autowired
  private Map<String, AlipayClientConfig> configMap;

  @Override
  public AlipayTradeWapPayResponse wapPay(AlipayWayPayRequest request) throws AlipayApiException {
    String method = "wapPay";
    log.debug("Enter {}", method);
    log.debug("WapPay form info : orderCode:【{}】 、orderTotalAmount:【{}】 "
            + "霸株、orderSubject:【{}】 雕沉、orderDescription:【{}】 、quitUrl:【{}】 去件、companyCode:【{}】坡椒。",
        request.getOrderCode(), request.getOrderTotalAmount(), request.getOrderSubject(),
        request.getOrderDescription(), request.getQuitUrl(), request.getCompanyCode()
    );
    AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest();
    alipayRequest.setNotifyUrl(alipayDetailConfig.getNotifyUrl());
    alipayRequest.setReturnUrl(alipayDetailConfig.getReturnUrl());
    AlipayTradeWapPayModel payModel = new AlipayTradeWapPayModel();
    //商戶訂單號
    payModel.setOutTradeNo(request.getOrderCode());
    //訂單總金額,單位為元尤溜,精確到小數(shù)點(diǎn)后兩位倔叼,取值范圍[0.01,100000000]
    payModel.setTotalAmount(request.getOrderTotalAmount().toString());
    //訂單標(biāo)題
    payModel.setSubject(request.getOrderSubject());
    //訂單描述
    payModel.setBody(request.getOrderDescription());
    //用戶付款中途退出返回商戶網(wǎng)站的地址
    payModel.setQuitUrl(request.getQuitUrl());
    //商品主類型  虛擬類商品不支持使用花唄渠道
    payModel.setGoodsType(AlipayConstant.VIRTUAL_GOODS_TYPE);
    //該筆訂單允許的最晚付款時(shí)間,逾期將關(guān)閉交易
    payModel.setTimeoutExpress(alipayDetailConfig.getTimeoutExpress());
    //銷售產(chǎn)品碼宫莱,與支付寶簽約的產(chǎn)品碼名稱
    payModel.setProductCode(AlipayConstant.WAP_PAY_PRODUCT_CODE);
    //設(shè)置回傳參數(shù)
    payModel.setPassbackParams(request.getCompanyCode());
    alipayRequest.setBizModel(payModel);
    //返回支付信息
    AlipayClient alipayClient = getAlipayClient(request.getCompanyCode());
    log.debug("Exit {}", method);
    return alipayClient.pageExecute(alipayRequest);
  }
  
  
    /**
   * 根據(jù)分公司code返回對應(yīng)的client.
   *
   * @param companyCode 分公司code.
   */
  private AlipayClient getAlipayClient(String companyCode) {
    AlipayClientConfig config = configMap.get(companyCode);
    return new DefaultAlipayClient(
        config.getGatewayUrl(),
        config.getAppId(),
        config.getAppPrivateKey(),
        config.getFormat(),
        config.getCharset(),
        config.getAlipayPublicKey(),
        config.getSignType()
    );
  }

至此缀雳,算是比較優(yōu)雅的實(shí)現(xiàn)了付款給指定商戶賬號。

后記:微信支付早就解決了這個問題 梢睛,也因此在社區(qū)里肥印,一大批吐槽者瘋狂吐槽支付寶的設(shè)計(jì)思路和實(shí)現(xiàn)方式。

image
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末绝葡,一起剝皮案震驚了整個濱河市深碱,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌藏畅,老刑警劉巖敷硅,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異愉阎,居然都是意外死亡绞蹦,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進(jìn)店門榜旦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來幽七,“玉大人,你說我怎么就攤上這事溅呢≡杪牛” “怎么了?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵咐旧,是天一觀的道長驶鹉。 經(jīng)常有香客問我,道長铣墨,這世上最難降的妖魔是什么室埋? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上姚淆,老公的妹妹穿的比我還像新娘孕蝉。我一直安慰自己,他們只是感情好肉盹,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著疹尾,像睡著了一般上忍。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上纳本,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天窍蓝,我揣著相機(jī)與錄音,去河邊找鬼繁成。 笑死吓笙,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的巾腕。 我是一名探鬼主播面睛,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼尊搬!你這毒婦竟也來了叁鉴?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤佛寿,失蹤者是張志新(化名)和其女友劉穎幌墓,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體冀泻,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡常侣,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了弹渔。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片胳施。...
    茶點(diǎn)故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖肢专,靈堂內(nèi)的尸體忽然破棺而出巾乳,到底是詐尸還是另有隱情,我是刑警寧澤鸟召,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布胆绊,位于F島的核電站,受9級特大地震影響欧募,放射性物質(zhì)發(fā)生泄漏压状。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望种冬。 院中可真熱鬧镣丑,春花似錦、人聲如沸娱两。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽十兢。三九已至趣竣,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間旱物,已是汗流浹背遥缕。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留宵呛,地道東北人单匣。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像宝穗,于是被迫代替她去往敵國和親户秤。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評論 2 348

推薦閱讀更多精彩內(nèi)容