An open API service indexing awesome lists of open source software.

https://github.com/portone-io/portone_flutter

Flutter App에서 포트원 V1 결제서비스 연동을 위한 모듈입니다.
https://github.com/portone-io/portone_flutter

certification flutter iamport payment portone

Last synced: 5 months ago
JSON representation

Flutter App에서 포트원 V1 결제서비스 연동을 위한 모듈입니다.

Awesome Lists containing this project

README

          

# portone_flutter
[![pub package](https://img.shields.io/pub/v/portone_flutter.svg)](https://pub.dev/packages/portone_flutter)

---
포트원 V1 플러터 모듈입니다.

## 목차
- [버전정보](CHANGELOG.md)
- [지원정보](SUPPORT.md)
- 설치하기
- 설정하기
- 공통 사항
- IOS 설정하기
- Android 설정하기
- [실시간 계좌이체 설정하기](example/manuals/TRANS.md)
- [예제](example/README.md)
- [콜백 함수 설정하기](example/manuals/CALLBACK.md)

## 버전정보
최신버전은 [v0.12.0](https://github.com/portone-io/portone_flutter/tree/main) 입니다. 버전 히스토리는 [버전정보](CHANGELOG.md)를 참고하세요.

## 지원정보
포트원 V1 플러터 모듈은 일반/정기결제 및 휴대폰 본인인증 기능을 지원합니다. 결제 모듈이 지원하는 PG사 및 결제수단에 대한 자세한 내용은 [지원정보](SUPPORT.md)를 참고해주세요.

## 설치하기
`pubspec.yaml` 파일에 `portone_flutter` 모듈을 추가해 귀하의 프로젝트에 포트원 V1 플러터 모듈을 설치할 수 있습니다.

```
dependencies:
portone_flutter: ^0.12.0
```

## 설정하기

### IOS 설정하기
IOS에서 포트원 V1 결제연동 모듈을 사용하기 위해서는 `info.plist` 파일에 아래 3가지 항목을 설정해주셔야 합니다. `[프로젝트 이름]/ios/Runner.xcworkspace` 파일을 열어 왼쪽 프로젝트 패널 > Runner > info.plist 파일을 클릭합니다.

#### 1. App Scheme 등록
외부 결제 앱(예) 페이코, 신한 판 페이)에서 결제 후 돌아올 때 사용할 URL identifier를 설정해야합니다.

![](assets/images/app-scheme-registry.gif)

1. `URL types` 속성을 추가합니다.
2. item `0`를 확장하여 `URL schemes` 속성을 추가합니다.
3. item `0`에 App URL Scheme 값(EX. example)을 작성합니다.

```html
...
CFBundleURLTypes


CFBundleTypeRole
Editor
CFBundleURLSchemes


example

...
```

#### 2. 외부 앱 리스트 등록
3rd party앱(예) 카드사 앱, 간편결제 앱 등)을 실행할 수 있도록 외부 앱 리스트를 등록해야합니다.

1. [LSApplicationQueriesSchemes](https://developer.apple.com/library/content/documentation/General/Reference/InfoPlistKeyReference/Articles/LaunchServicesKeys.html#//apple_ref/doc/uid/TP40009250-SW14) 속성을 추가합니다.
2. 외부 앱 URL Scheme 값을 하나씩 추가합니다.

```html
...
LSApplicationQueriesSchemes

kftc-bankpay
ispmobile
itms-apps
hdcardappcardansimclick
smhyundaiansimclick
shinhan-sr-ansimclick
smshinhanansimclick
kb-acp
mpocket.online.ansimclick
ansimclickscard
ansimclickipcollect
vguardstart
samsungpay
scardcertiapp
lottesmartpay
lotteappcard
cloudpay
nhappcardansimclick
nonghyupcardansimclick
citispay
citicardappkr
citimobileapp
kakaotalk
payco
lpayapp
hanamopmoasign
wooripay
nhallonepayansimclick
hanawalletmembers
chaipayment
kb-auth
hyundaicardappcardid
com.wooricard.wcard
lmslpay
lguthepay-xpay
liivbank
supertoss
newsmartpib
naversearchthirdlogin

...
```

#### 3. App Transport Security 설정

![](assets/images/allow-arbitrary.gif)

1. `App Transport Security Settings` 속성에 [Allow Arbitrary Loads in Web Content](https://developer.apple.com/documentation/bundleresources/information_property_list/nsapptransportsecurity/nsallowsarbitraryloadsinwebcontent) 속성을 추가합니다.
2. 그 값을 `true`로 설정합니다.

```html
...
NSAppTransportSecurity


NSAllowsArbitraryLoadsInWebContent

NSAllowsArbitraryLoads

...
```

#### 4. PASS 앱 Universal Link 설정 (선택 사항)
Push 알림 없이 PASS 앱(SKT PASS, KT 인증, U+인증)을 실행해 본인인증을 진행하기 위해서는 `mRedirectUrl` 파라미터 설정이 필요합니다.

##### 4.1 mRedirectUrl 설정
본인인증 요청 시 `CertificationData` 객체의 `mRedirectUrl` 파라미터에 `UrlData.redirectUrl` 값을 설정해 주세요. 다날의 경우, `mRedirectUrl` 설정 시 `carrier` 파라미터로 전달한 통신사 선택을 사용자가 변경할 수 없으므로 주의해주세요.

```dart
import 'package:portone_flutter/model/certification_data.dart';
import 'package:portone_flutter/model/url_data.dart'; // UrlData import 추가

// ...

CertificationData data = CertificationData(
mRedirectUrl: UrlData.redirectUrl
// ... 기타 본인인증 데이터
);

// ...
```

### Android 설정하기
안드로이드 API 레벨 30에서 특정 카드사로 결제 시도시 `net::ERR_CLEARTEXT_NOT_PERMITTED` 오류가 발생한다는 버그가 보고되었습니다. 이를 해결하기 위해서는 [AndroidManifest.xml](https://github.com/portone-io/portone_flutter/blob/develop/example/android/app/src/main/AndroidManifest.xml#L13) 파일에 아래와 같이 [usesclearTextTraffic](https://developer.android.com/guide/topics/manifest/application-element#usesCleartextTraffic) 속성을 `true`로 설정해주셔야 합니다.

```xml

...

```

### 실시간 계좌이체 설정하기
웹 표준 이니시스와 나이스 정보통신은 뱅크페이 앱을 통해 실시간 계좌이체를 진행합니다. 뱅크페이에서 결제 인증 후 본래의 앱으로 복귀 해 다음단계로 진행을 하려면 별도 설정이 요구됩니다. 자세한 내용은 [실시간 계좌이체 설정하기](example/manuals/TRANS.md)를 참고해주세요.

## 예제
포트원 V1 플러터 모듈로 아래와 같이 일반/정기결제 및 휴대폰 본인인증 기능을 구현할 수 있습니다. 보다 자세한 내용은 [예제](example/README.md)를 참고하세요.

#### 일반/정기결제 예제
```dart
import 'package:flutter/material.dart';

/* 포트원 V1 결제 모듈을 불러옵니다. */
import 'package:portone_flutter/iamport_payment.dart';
/* 포트원 V1 결제 데이터 모델을 불러옵니다. */
import 'package:portone_flutter/model/payment_data.dart';

class Payment extends StatelessWidget {
@override
Widget build(BuildContext context) {
return IamportPayment(
appBar: new AppBar(
title: new Text('포트원 V1 결제'),
),
/* 웹뷰 로딩 컴포넌트 */
initialChild: Container(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset('assets/images/iamport-logo.png'),
Padding(padding: EdgeInsets.symmetric(vertical: 15)),
Text('잠시만 기다려주세요...', style: TextStyle(fontSize: 20)),
],
),
),
),
/* [필수입력] 가맹점 식별코드 */
userCode: 'iamport',
/* [필수입력] 결제 데이터 */
data: PaymentData(
pg: 'html5_inicis', // PG사
payMethod: 'card', // 결제수단
name: '포트원 V1 결제데이터 분석', // 주문명
merchantUid: 'mid_${DateTime.now().millisecondsSinceEpoch}', // 주문번호
amount: 39000, // 결제금액
buyerName: '홍길동', // 구매자 이름
buyerTel: '01012345678', // 구매자 연락처
buyerEmail: 'example@naver.com', // 구매자 이메일
buyerAddr: '서울시 강남구 신사동 661-16', // 구매자 주소
buyerPostcode: '06018', // 구매자 우편번호
appScheme: 'example', // 앱 URL scheme
cardQuota : [2,3] //결제창 UI 내 할부개월수 제한
),
/* [필수입력] 콜백 함수 */
callback: (Map result) {
Navigator.pushReplacementNamed(
context,
'/result',
arguments: result,
);
},
);
}
}
```

#### 본인인증 예제

이니시스 통합인증의 경우 다날 휴대폰 본인인증과 달리 `mRedirectUrl` 파라미터를 필수로 설정해주셔야 합니다.

##### 다날 휴대폰 본인인증
```dart
import 'package:flutter/material.dart';

/* 포트원 V1 휴대폰 본인인증 모듈을 불러옵니다. */
import 'package:portone_flutter/iamport_certification.dart';
/* 포트원 V1 휴대폰 본인인증 데이터 모델을 불러옵니다. */
import 'package:portone_flutter/model/certification_data.dart';

class Certification extends StatelessWidget {
@override
Widget build(BuildContext context) {
return IamportCertification(
appBar: new AppBar(
title: new Text('포트원 V1 본인인증'),
),
/* 웹뷰 로딩 컴포넌트 */
initialChild: Container(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset('assets/images/iamport-logo.png'),
Padding(padding: EdgeInsets.symmetric(vertical: 15)),
Text('잠시만 기다려주세요...', style: TextStyle(fontSize: 20)),
],
),
),
),
/* [필수입력] 가맹점 식별코드 */
userCode: 'iamport',
/* [필수입력] 본인인증 데이터 */
data: CertificationData(
pg: 'danal', // PG사
merchantUid: 'mid_${DateTime.now().millisecondsSinceEpoch}', // 주문번호
company: '포트원 V1', // 회사명 또는 URL
carrier: 'SKT', // 통신사
name: '홍길동', // 이름
phone: '01012341234', // 전화번호
),
/* [필수입력] 콜백 함수 */
callback: (Map result) {
Navigator.pushReplacementNamed(
context,
'/result',
arguments: result,
);
},
);
}
}
```
##### 이니시스 통합인증
```dart
import 'package:flutter/material.dart';

/* 포트원 V1 휴대폰 본인인증 모듈을 불러옵니다. */
import 'package:portone_flutter/iamport_certification.dart';
/* 포트원 V1 휴대폰 본인인증 데이터 모델을 불러옵니다. */
import 'package:portone_flutter/model/certification_data.dart';

class Certification extends StatelessWidget {
@override
Widget build(BuildContext context) {
return IamportCertification(
appBar: new AppBar(
title: new Text('포트원 V1 본인인증'),
),
/* 웹뷰 로딩 컴포넌트 */
initialChild: Container(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset('assets/images/iamport-logo.png'),
Padding(padding: EdgeInsets.symmetric(vertical: 15)),
Text('잠시만 기다려주세요...', style: TextStyle(fontSize: 20)),
],
),
),
),
/* [필수입력] 가맹점 식별코드 */
userCode: 'iamport',
/* [필수입력] 본인인증 데이터 */
data: CertificationData(
pg: 'inicis_unified', // PG사
merchantUid: 'mid_${DateTime.now().millisecondsSinceEpoch}', // 주문번호
mRedirectUrl: 'https://example.com', // 본인인증 후 이동할 URL
),
/* [필수입력] 콜백 함수 */
callback: (Map result) {
Navigator.pushReplacementNamed(
context,
'/result',
arguments: result,
);
},
);
}
}
```

## 콜백 함수 설정하기
콜백 함수는 필수입력 필드로, 결제/본인인증 완료 후 라우트 이동을 위해 아래와 같이 로직을 작성할 수 있습니다. 콜백 함수에 대한 자세한 설명은 [콜백 설정하기](example/manuals/CALLBACK.md)를 참고하세요.

```dart
...
callback: (Map result) {
Navigator.pushReplacementNamed(
context,
'/result',
arguments: result,
);
},
...
```