본문 바로가기

웹 개발 알아두기

결제서비스 - 스트라이프

반응형

전자상거래 사이트에서 결제 서비스는 빠질 수 없는 기능 중 하나입니다. 결제서비스는 고객정보를 포함하기 때문에 이를 직접 개발하는 데는 많은 시간과 비용이 소모됩니다. 이러한 이유로 많은 사이트에서 전문서비스를 사용하는데 그중 스트라이프를 사용하는 방법을 보겠습니다.

목차

스트라이프?

스트라이프는 결재 서비스 시스템 (PSP)으로 고객과 판매자와 소비자 사이에서 안전한 결재를 돕습니다. 구글, 줌, 쇼피파이, 아마존 등 이름 있는 고객들을 확보하고 있으며, 커스터마이징의 폭이 넓고 완성도 있는 가이드를 제공하기 때문에 많은 지지를 받고 있습니다. 또, 실제 구매가 일어나지 않는 경우 비용이 들지 않기 때문에 애플리케이션 테스트 목적으로 사용이 가능하다는 장점이 있습니다.

결재진행 과정

결재는 크게 강화된 기준과 일반 기준에 따라 과정이 달라집니다.

▶ 일반 기준

일반 기준의 결재는 서버에 대한 유저의 구매요청이 성공적인 경우 스트라이프에서 토큰을 생성해서 유저에게 보내주고 유저는 해당 토큰을 서버를 거쳐 다시 스트라이프로 전송하여 일치하는 경우 완료됩니다.

▶ 강화 기준

강화된 기준의 경우, 사용자가 구매의사를 표시하면 시크릿이 부여되고 최종 결재가 이루어지면 부여된 시크릿을 통해 사용자를 확인하고 결재가 완료됩니다. 서버의 경우 스트라이프가 사용자에게 결재를 승인할 때 발생되는 이벤트를 감지하여 결재완료 여부를 확인합니다.

스트라이프 계정생성

스트라이프 사이트에서 계정을 생성하면 아래와 같은 화면이 뜹니다. 테스트 모드에서 프로젝트를 생성합니다.

계정생성이 완료되면 원하는 애플리케이션과 연결작업을 하면 됩니다.

애플리케이션 연결하기

앵귤러 & 닷넷 웹 에이피아이

강화된 기준으로 풀스택 애플리케이션 .NET, 앵귤러와 연결하는 방법을 보겠습니다.

닷넷

에이피아이 프로젝트 생성
 

.NET 웹 에이피아이 생성하기

개발도구 설치하기 .NET을 이용하여 웹애플리케이션을 만들기 위해서는 .NET에서 제공하는 개발도구가 필요합니다. 개발도구 다운로드는 아래 링크에서 가능합니다. .NET | Free. Cross-platform. Open Sour

jin-co.tistory.com

데이터베이스 설치
 

시퀄라이트 사용하기 - 코드 우선 방식

.NET은 데이터베이스를 생성할 때 작성된 코드를 통해 데이터베이스를 생성하는 Code first (코드우선) 방식과 데이터베이스의 데이터를 바탕으로 코드를 작성하는 data first (데이터 우선) 방식을 제

jin-co.tistory.com

인증된 호스트 설정

전자상거래 결제의 경우 인증된 도메인을 사용해야 합니다. 닷넷은 기본적으로 구동 시 http와 https 각각 도메인에서 모두 구동하도록 되어있으나 편리를 위해 http 호스트를 삭제하고

https주소를 하나로 통일

패키지 설치

누겟 갤러리를 열고 아래 패키지를 설치합니다

Stripe.net

환경변수 설정

서비스와 애플리케이션을 연결하려면 에이피아이 키가 필요합니다. 이를 얻기 위해 스트라이프 계정으로 이동하여 개발자메뉴를 선택한 후 'API keys'를 선택합니다. 퍼블릭 키와 시크릿 키를 차례로 복사하여

애플리케이션의 appsettings 파일에 넣습니다 (개발파일 'appsetting.Development.json'이나 배포파일 'appsetting.json' 어디든 관계없으나 배포파일이 조금 더 안전하므로 배포파일에 생성합니다)

엔티티 생성

결제과정에 필요한 정보수집을 위해 엔티티를 생성하고 속성을 추가. 이때, 하나의 결제상태를 관리하고 필요시 수정을 위한 아이디와 결제완료확인을 위한 시크릿을 반드시 추가합니다

인텐트 인터페이스 생성

결제가 시작될 때 결재아이디를 생성하기 위한 인터페이스를 생성합니다

인텐트 인터페이스 구현

구현 클래스를 생성하고 컨스트럭터를 추가한 뒤 필요한 기능들을 인젝션 합니다 (IConfiguration은 설정한 환경변수 사용을 위해 필요).

구현된 메서드를 아래와 같이 수정합니다

public async Task<Payment> UpdatePaymentIntent(int id)
{
  StripeConfiguration.ApiKey = _config["Stripe:SecretKey"];
  var payment = await _payRepo.GetPayByIdAsync(id);      

  var service = new PaymentIntentService();
  PaymentIntent intent;
  if (string.IsNullOrEmpty(payment.PaymentIntentId))
  {
    var options = new PaymentIntentCreateOptions
    {
      Amount = (long) (100),
      Currency = "usd",
      PaymentMethodTypes = new List<string> { "card" }
    };
    intent = await service.CreateAsync(options);
    payment.PaymentIntentId = intent.Id;
    payment.ClientSecret = intent.ClientSecret;
  }
  else
  {
    var options = new PaymentIntentUpdateOptions
    {
      Amount = (long) (100),
    };
    await service.UpdateAsync(payment.PaymentIntentId, options);
  }      
  return payment;
}
인텐트 인터페이스 서비스 등록

Program.cs 파일에 생성한 인터페이스를 서비스로 등록합니다

레포지토리 인터페이스 구성

데이터를 처리할 레포지토리 생성을 위해 인터페이스 구성

레포지토리 인터페이스 구현

레포지토리 클래스를 생성하고 콘텍스트를 주입

인터페이스 구현 및 메서드 수정

레포지토리 서비스 등록

Program.cs 파일에 생성한 인터페이스를 서비스로 등록합니다

컨트롤러 생성

엔드포인트 지정을 위해 컨트롤러를 생성하고 스트라이프 서비스와 레포지토리 주입

엔드포인트 설정

앱 실행

API 폴더로 이동하여

cd /API

아래 명령어로 앱을 실행합니다.

dotnet watch

포스트 요청으로 아래와 같이 클라이언트 시크릿과 인텐트아이디가 반환되면 1차 작업완료

앵귤러

콘솔을 열고 프로젝트 루트에서 앵귤러 프로젝트를 생성합니다.

전자상거래 결제의 경우 인증서가 설치된 도메인을 사용해야 하므로 인증서를 설치합니다.

인증서 설치
 

앵귤러 - 로컬에서 인증 URL (HTTPS) 사용하기

개발환경에서 앵귤러 애플리케이션을 구동하면 기본적으로 http 프로토콜을 사용합니다. mkcert라는 라이브러리를 활용하여 인증서를 설치하고 로컬환경에서 https를 사용하는 방법을 보겠습니다.

jin-co.tistory.com

스트라이프 제이에스 설치

앵귤러 프로젝트 콘솔에 아래 명령어 실행

npm install @stripe/stripe-js

컨포넌트 생성

컴포넌트를 생성하고

템플릿 코드를 아래와 같이 작성 (속성변수는 나중에 클래스에서 스트라이프 제이에스 요소와 연결하는 데 사용)

<!-- pay.component.html -->

<div>
  <div type="text" class="form-control" #cardNum></div>
  <div type="text" class="form-control" #cardExp></div>
  <div type="text" class="form-control" #cardCvc></div>
  <button class="btn" (click)="onSubmit()">Submit</button>
</div>
<span class="text-danger">
  {{stripeErrors}}
</span>

클래스 파일에서 뷰차일드를 통해 설정한 요소를 가져오고 해당 요소에 스트라이프 요소를 연결합니다.

// pay.component.ts

import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import {
  Stripe,
  StripeCardCvcElement,
  StripeCardExpiryElement,
  StripeCardNumberElement,
  StripeElementChangeEvent,
  loadStripe,
} from '@stripe/stripe-js';

@Component({
  selector: 'app-pay',
  templateUrl: './pay.component.html',
  styleUrls: ['./pay.component.css'],
})
export class PayComponent implements OnInit {
  @ViewChild('cardNum') cardNumEl?: ElementRef;
  @ViewChild('cardExp') cardExpEl?: ElementRef;
  @ViewChild('cardCvc') cardCvcEl?: ElementRef;
  stripe: Stripe | null = null;
  cardNum?: StripeCardNumberElement;
  cardExp?: StripeCardExpiryElement;
  cardCvc?: StripeCardCvcElement;
  stripeErrors: any;
  clientSecret: string = '<clientSecret>';

  constructor() {}

  ngOnInit(): void {
    loadStripe(
      '<publicSecretKey>'
    ).then((stripe) => {
      this.stripe = stripe;
      const el = stripe?.elements();
      if (el) {
        this.cardNum = el.create('cardNumber');
        this.cardNum.mount(this.cardNumEl?.nativeElement);
        this.showStripeError(this.cardNum);

        this.cardExp = el.create('cardExpiry');
        this.cardExp.mount(this.cardExpEl?.nativeElement);
        this.showStripeError(this.cardExp);

        this.cardCvc = el.create('cardCvc');
        this.cardCvc.mount(this.cardCvcEl?.nativeElement);
        this.showStripeError(this.cardCvc);
      }
    });
  }

  showStripeError(el: any) {
    el.on('change', (e: StripeElementChangeEvent) => {
      if (e.error) {
        this.stripeErrors = e.error.message;
      } else {
        this.stripeErrors = null;
      }
    });
  }

  onSubmit() {
    console.log('card num: ', this.cardNum);
    this.stripe
      ?.confirmCardPayment(this.clientSecret, {
        payment_method: {
          card: this.cardNum!,
        },
      })
      .then((result) => {
        console.log(result);
      });
  }
}

위 코드에서 <publicSecretKey>는 스트라이프 계정에서 에이피아이 퍼블릭 키로 교체 후 앱을 구동하면

스트라이프 제이에스와 연결된 요소확인이 가능합니다.

결제 테스트

결제 테스트를 위해 서버에서 생성한 클라이언트 시크릿을 복사하여 <clientSecret> 칸에 넣고 전송. 참고로, 테스트용 카드 번호는 4242...입니다.

스트라이프에서 아래와 같이 확인이 되면 성공

이벤트 테스트

스트라이프에는 개발자가 활용가능한 다양한 이벤트를 제공합니다. 이벤트를 테스트하는 방법도 보겠습니다.

 

스트라이프 개발자 모드 -> 웹 훅 메뉴 -> 엔드포인트 추가 선택

이벤트 추가 (select events) 선택

이벤트 중 페이먼트 인텐트 박스 열기

페이성공과 실패 이벤트 선택 후 저장 버튼 (add evetns) 누름

엔드포인트 추가 버튼 (add endpoint) 선택

테스트 메뉴를 선택하면 스트라이프 씨엘아이가 필요하다고 합니다 (설치 안내)

윈도의 경우 파워쉘을 열고 아래 커맨드를 차례로 입력

Set-ExecutionPolicy RemoteSigned -Scope CurrentUser

irm get.scoop.sh | iex

커맨드라인 관리자로 실행

scoop bucket add stripe https://github.com/stripe/scoop-stripe-cli.git
scoop install stripe --global

프로젝트 콘솔을 열고 스트라이프 씨엘아이 설치확인

stripe --version

스트라이프 로그인

stripe login

브라우저를 열고 (열리지 않는 경우 경로를 복사하여 다른 브라우저로 시도) 접근허가

접근이 허용되면 완성

 

stripe listen --forward-to <url>

private const string Secret = "whsec_3711bc92b2c6a9d9ed";

[HttpPost("webhook")]
public async Task<ActionResult> StripeWebhook()
{
  var json = await new StreamReader(Request.Body).ReadToEndAsync();
  var stripeEvent = EventUtility.ConstructEvent(json, Request.Headers["Stripe-Signature"], Secret);
  PaymentIntent intent;
  Order order;
  switch (stripeEvent.Type)
  {
    case "payment_intent.succeeded":
      intent = (PaymentIntent)stripeEvent.Data.Object;
      break;
    case "payment_intent.payment_failed":
      intent = (PaymentIntent)stripeEvent.Data.Object;
      break;
  }

  return new EmptyResult();
}

이상으로 결제서비스 스트라이프를 사용하는 방법을 보았습니다.


참고

Stripe | Payment Processing Platform for the Internet

 

Stripe | Payment Processing Platform for the Internet

Stripe is a suite of APIs powering online payment processing and commerce solutions for internet businesses of all sizes. Accept payments and scale faster.

stripe.com

Stripe JS Reference

 

Stripe JS Reference

 

stripe.com

GitHub - stripe/stripe-js: Loading wrapper for Stripe.js

 

GitHub - stripe/stripe-js: Loading wrapper for Stripe.js

Loading wrapper for Stripe.js. Contribute to stripe/stripe-js development by creating an account on GitHub.

github.com

Get started with the Stripe CLI | Stripe Documentation

 

Get started with the Stripe CLI

Build, test, and manage your Stripe integration directly from the command line.

stripe.com

Scoop

 

https://scoop.sh/

 

scoop.sh

How Does Stripe Work? 2023 Guide To Using Stripe Payments (merchantmaverick.com)

 

How Does Stripe Work? The Complete Guide To Stripe For Business

What is Stripe Payments? Learn how Stripe works, what industries the company supports, & whether Stripe is a good choice for your business.

www.merchantmaverick.com

 

728x90
반응형

'웹 개발 알아두기' 카테고리의 다른 글

택배사 운송 조회 (롯데, 우체국)  (0) 2023.12.19
폴더에서 프로그램 열기  (0) 2023.08.31
패키지 매니저  (4) 2023.02.01
환경변수 사용하기  (0) 2023.01.23
Single-Page-Application  (0) 2023.01.19