Vue 프로젝트에서 WeChat H5 결제 연동 구현하기

WeChat 브라우저 환경 결제 연동 개요

모바일 웹 환경(H5) 에서 WeChat 내부 결제를 수행하려면 사용자의 OpenID 확보와 JSBridge 를 통한 결제 요청 전송이 필수적입니다. 일반적으로 Vue 프레임워크를 기반으로 하더라도 WeChat 특유의 인증 프로세스를 먼저 통과해야 하며, 이후 서버 측에서 발급받은 결제 토큰을 사용하여 정산 흐름을 시작합니다.

1. 사용자 인증 및 OpenID 획득 전략

초기 진입 시 로컬 저장소에 저장된 인증 식별자가 존재하는지 확인해야 합니다. 식별자가 누락된 경우 WeChat 공개 플랫폼 API 를 통해 OAuth 인증 절차를 재개행하고, 성공적으로 반환된 정보를 캐시합니다. 현대적인 자바스크립트 표준인 URLSearchParams 를 활용하여 쿼리 파라미터 처리를 개선했습니다.

// 컴포넌트 마운트 시 인증 상태 검증
<span class="keyword">async verifyAuthorizationStatus() </span>{
  const existingId = localStorage.getItem('wechat_user_uid');
  
  if (!existingId || existingId === 'null') {
    await <span class="keyword">this</span>.initWechatOAuthFlow();
  }
}

<span class="keyword">async initWechatOAuthFlow() </span>{
  const paramParser = new URLSearchParams(window.location.search);
  const accessCode = paramParser.get('code');
  const currentPath = window.location.href;

  if (!accessCode) {
    // 코드 미발견 시 WeChat 인증 센터로 리디렉션
    const configAppId = process.env.VUE_APP_WECHAT_APPID;
    const oauthUrl = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${configAppId}&redirect_uri=${encodeURIComponent(currentPath)}&response_type=code&scope=snsapi_base#wechat_redirect`;
    window.location.href = oauthUrl;
  } else {
    // 코드가 있을 때 백엔드 호출을 통해 실제 ID 변환
    await <span class="keyword">this</span>.exchangeCodeForUid(accessCode);
  }
}

<span class="keyword">async exchangeCodeForUid(code) </span>{
  try {
    const response = await httpClient.post('/api/auth/wechat-uid', { code });
    if (response.data.success) {
      localStorage.setItem('wechat_user_uid', response.data.uid);
    }
  } catch (error) {
    console.error('인증 실패', error);
  }
}

2. WeChat JSBridge 를 통한 결제 트리거

결제 요청은 반드시 WeChat 브라우저 내에서만 동작하며, WeixinJSBridge 객체의 invoke 메서드를 사용합니다. 필요한 결제 파라미터들은 서버 측 사전 결제 인터페이스를 통해 생성된 데이터를 클라이언트로 전달받아 주입해야 합니다.

<span class="keyword">const executeMobilePayment(paymentData) </span> {
  const { appId, timeStamp, nonStr, signString, prePayId } = paymentData;
  
  WeixinJSBridge.invoke(
    'getBrandWCPayRequest',
    {
      appId: appId,
      timeStamp: timeStamp,
      nonceStr: nonStr,
      package: 'prepay_id=' + prePayId,
      signType: 'RSA',
      paySign: signString
    },
    (response) => {
      switch (response.err_msg) {
        case 'get_brand_wcpay_request:ok':
          showNotification('결제가 완료되었습니다.', 'success');
          router.push({ path: '/payment/result' });
          break;
        case 'get_brand_wcpay_request:fail':
          showNotification('결제 중 오류가 발생했습니다.', 'error');
          break;
        case 'get_brand_wcpay_request:cancel':
          showNotification('사용자가 결제를 취소했습니다.', 'warning');
          break;
      }
    }
  );
}

태그: vue wechat-pay h5 jssdk frontend-integration

6월 17일 04:19에 게시됨