웹훅을 설정하면 Paxful 마켓플레이스에서 이벤트 발생 시 실시간으로 HTTPS 알림을 받을 수 있습니다. 예를 들면 신규 거래가 시작되거나 거래 파트너가 거래 채팅에서 메시지를 보냈을 때 알림을 보내드리게 됩니다. 웹훅을 사용하면 발생한/발생하지 않은 오브젝트를 변경하고자 API를 쿼리할 필요가 없어집니다. 또한, 가격 제한까지 도달하는 일이 없도록 막아줍니다. 이번 가이드에서는 Paxful에서 웹훅을 설정하는 방법을 차근차근 설명해드리겠습니다.
Paxful은 다음과 같은 이벤트 발생 시 웹훅을 지원합니다.
- Paxful에서 거래 금액을 수신 중인 경우
- 거래 채팅에서 메시지를 받은 경우
- 거래 채팅에서 첨부 파일을 받은 경우
- 누군가 내 Paxful 프로필을 조회하는 경우
- 누군가 내 오퍼를 조회하는 경우
- 거래 파트너가 암호화폐 대금을 결제한 경우
- 거래가 취소되거나 만료된 경우
- 암호화폐 판매 완료
- 암호화폐 구매 완료
- 암호화폐 입금 확인 완료
- 암호화폐 입금을 수신 대기 중인 경우
- 거래 파트너에게서 피드백을 받은 경우
- 새로 피드백 회신을 받은 경우
웹훅 설정하기
참조: 서비스에서 웹훅을 받을 준비가 되었는지 확인해주세요. URL 저장 절차 중에 서비스가 "X-Paxful-Request-Challenge" 요청 헤더를 가지며, 이 내용을 그대로 응답에 넣어야 합니다.
페이로드에서 Paxful 요청 헤더는 다음 그림과 같이 나타납니다(웹훅 서비스의 예시로 Node.js를 사용해보았습니다).

1. Paxful 계정에 로그인하고 페이지의 상단 오른쪽에 표시된 사용자 이름 위에 마우스 커서를 올리세요. 그다음 나타나는 메뉴에서 설정을 클릭합니다.

설정 페이지가 표시됩니다.
2. 페이지 왼쪽 메뉴에서 개발자를 클릭합니다.

개발자 페이지가 표시됩니다.
3. API 키가 없는 경우, 아래 입력란에 2FA 코드를 입력하고 새로운 API 키 추가를 클릭합니다. API 키가 있다면 이 단계를 건너뛰셔도 됩니다.

추가 섹션과 함께 새 API 키가 개발자 페이지에 표시됩니다.
4. 앱에서 URL을 복사합니다.
Paxful 개발자 페이지에서 웹훅 섹션으로 이동하세요. 링크를 the URL 요청 필드에 붙여넣고 저장을 클릭합니다.
주의: Paxful 웹훅은 HTTPS 주소 유형으로만 지원됩니다. HTTP 주소는 웹훅 목적으로 사용하실 수 없으니 유의해주세요.

앱으로 요청 헤더를 보냅니다.
참조: 요청의 유효 기간은 10초입니다. 앱에서 응답을 받지 못하는 경우, URL이 저장되지 않으며 웹훅도 생성되지 않습니다.
5. 성공하면 알림을 받을 수 있는 이벤트 목록이 아래에 표시됩니다. 이벤트 구독 목록에서 선택상자를 체크해 원하는 이벤트를 선택하세요.

참조:
- 선택을 완료하면 이벤트가 자동 저장됩니다.
-
앱으로 이벤트 정보를 전송하는 데 3회 실패한 경우, 웹훅(URL)이 비활성화됩니다. 웹훅 호출(콜)의 유효 기간은 3초입니다.
-
새 링크를 삽입하려면 현재 URL을 새 URL로 바꾸고 변경하기를 클릭하세요.
-
웹훅을 완전히 비활성화하려면 삭제를 클릭하세요.
- 비활성화한 URL을 다시 활성화하려면 재시도를 클릭하세요.
요청 URL을 정상적으로 저장한 경우, 앱에서 이벤트가 아래와 같이 표시됩니다.

Paxful에서 로그인 요청 전송
Paxful에서 앱을 위해 고유 스트링을 생성하고 공유해드립니다. Paxful에서 보낸 인증 요청으로 시크릿 서명 시 사용하는 서명을 인증할 수 있습니다.
HTTPS 요청을 전송할 때마다 Paxful에서 "X-Paxful-Signature" HTTPS 헤더를 추가합니다. 서명은 서명 시크릿과 표준 HMAC-SHA256 키 해시를 사용해 전송하는 요청 본문(바디)를 조합하여 생성합니다.
참조: 결과적으로 생성된 서명은 각 요청마다 고유하며, 시크릿 정보를 직접 포함하지 않습니다. 이를 통해 앱을 안전하게 보호하고 악성 행위자가 앱을 악용하는 사고를 막을 수 있습니다.
JavaScript의 예시
const crypto = require('crypto');
const express = require('express');
const app = express();
const port = 3000;
const bodyParser = require('body-parser');
https://paxful.com/account/developer 페이지의 API 시크릿:
const apiSecret = 'maE5KV16FV0nDyh7XPm2F8f8FZTdtb5p';
app.use(bodyParser.json());
서비스 주소 인증 요청을 받는 경우, 요청에서 "X-Paxful-Request-Challenge" 헤더를 뺀 다음 응답에 넣으세요.
app.use((req, res, next) => {
주소 인증 요청은 페이로드나 요청 서명을 포함하지 않습니다.
if (!Object.keys(req.body).length && !req.get('X-Paxful-Signature')) {
console.log('Address verification request received.');
const challengeHeader = 'X-Paxful-Request-Challenge';
res.set(challengeHeader, req.get(challengeHeader));
res.end();
} else {
next();
}
});
이벤트 알림을 받은 경우 "X-Paxful-Signature" 헤더를 확인하셔야 합니다. 요청에 잘못된 서명이 포함된 경우 처리하지 마세요.
app.use((req, res, next) => {
const providedSignature = req.get('X-Paxful-Signature');
const calculatedSignature = crypto.createHmac('sha256', apiSecret).update(JSON.stringify(req.body)).digest('hex');
if (providedSignature !== calculatedSignature) {
console.log('Request signature verification failed.');
res.status(403).end();
} else {
next();
}
});
이제 이벤트를 처리하실 수 있습니다.
app.post('*', async (req, res) => {
console.log('New event received:');
console.log(req.body);
res.end();
});
app.listen(port, () => console.log(`Example app listening at http://localhost:${port}`));
추가 질문이 있다면 지원팀에 문의해주세요. 또, 개발자 문서에서 API 서비스를 더 자세히 알아보실 수 있습니다.