Как интегрировать платежный шлюз Stripe в Django REST Framework: Пошаговое руководство

Интеграция платежной системы Stripe с Django REST Framework позволяет создавать мощные и гибкие решения для обработки онлайн-платежей. Это особенно актуально для проектов, где требуется масштабируемое API для взаимодействия с frontend-приложениями.

Зачем интегрировать Stripe в Django REST Framework?

  • Удобство и скорость разработки: Stripe предоставляет готовые инструменты и API, значительно упрощающие процесс интеграции платежей.
  • Гибкость и масштабируемость: Django REST Framework обеспечивает создание RESTful API, которые легко масштабируются и интегрируются с различными frontend-технологиями.
  • Безопасность: Stripe берет на себя ответственность за обработку платежных данных, снижая риски для вашего приложения.
  • Широкие возможности: Stripe поддерживает различные методы оплаты, подписки, выставление счетов и многое другое.

Обзор Stripe и его возможностей для Django проектов

Stripe — это платформа для онлайн-платежей, предоставляющая API для интеграции в веб-сайты и приложения. Основные возможности:

  • Платежи: Обработка кредитных и дебетовых карт, а также других методов оплаты (Apple Pay, Google Pay и т.д.).
  • Подписки: Управление подписками и автоматическое списание средств.
  • Выставление счетов: Создание и отправка счетов клиентам.
  • Stripe Connect: Подключение и управление сторонними продавцами.

Для Django проектов Stripe предоставляет удобный Python-пакет, упрощающий взаимодействие с API.

Необходимые инструменты и библиотеки (Python, Stripe, Django REST Framework)

  • Python: Язык программирования, на котором написан Django.
  • Django REST Framework: Мощный инструмент для создания REST API в Django.
  • Stripe Python library: Официальная библиотека Stripe для Python.
  • Django: Python Web Framework

Настройка Stripe и Django проекта

Создание аккаунта Stripe и получение API ключей

  1. Зарегистрируйтесь на сайте Stripe (https://stripe.com).
  2. Перейдите в раздел «Developers» -> «API keys» и получите секретный (Secret key) и публичный (Publishable key) ключи. Сохраните эти ключи в безопасном месте.

Установка Django REST Framework и необходимых пакетов (stripe python library)

pip install djangorestframework stripe
# settings.py

INSTALLED_APPS = [
    ...
    'rest_framework',
]

STRIPE_SECRET_KEY = 'sk_test_...'  # Замените на ваш секретный ключ
STRIPE_PUBLISHABLE_KEY = 'pk_test_...' # Замените на ваш публичный ключ

Настройка Django проекта для работы с REST API

  1. Добавьте rest_framework в INSTALLED_APPS.
  2. Установите секретный ключ Stripe в настройках Django.

Реализация API для работы с платежами

Создание сериализаторов для обработки данных о платежах

# serializers.py

from rest_framework import serializers

class PaymentSerializer(serializers.Serializer):
    amount = serializers.IntegerField(required=True, min_value=1)
    currency = serializers.CharField(required=True, max_length=3, default='usd')
    description = serializers.CharField(required=False, allow_blank=True)

    def validate_amount(self, value: int) -> int:
        """Validates that the amount is a positive integer."""
        if value <= 0:
            raise serializers.ValidationError("Amount must be a positive integer.")
        return value

    def validate_currency(self, value: str) -> str:
        """Validates that the currency is a 3-letter ISO currency code."""
        if len(value) != 3:
            raise serializers.ValidationError("Currency must be a 3-letter ISO code.")
        return value.lower()

Разработка API endpoints для создания платежей (Create Checkout Session)

# views.py

import stripe
from django.conf import settings
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .serializers import PaymentSerializer

stripe.api_key = settings.STRIPE_SECRET_KEY

class CreateCheckoutSessionView(APIView):
    def post(self, request):
        serializer = PaymentSerializer(data=request.data)
        if serializer.is_valid():
            try:
                validated_data = serializer.validated_data
                checkout_session = stripe.checkout.Session.create(
                    payment_method_types=['card'],
                    line_items=[
                        {
                            'price_data': {
                                'currency': validated_data['currency'],
                                'product_data': {
                                    'name': validated_data.get('description', 'Payment'),
                                },
                                'unit_amount': validated_data['amount'],
                            },
                            'quantity': 1,
                        },
                    ],
                    mode='payment',
                    success_url=request.build_absolute_uri('/success/') + '?session_id={CHECKOUT_SESSION_ID}',
                    cancel_url=request.build_absolute_uri('/cancel/'),
                )
                return Response({'id': checkout_session.id}, status=status.HTTP_200_OK)
            except Exception as e:
                return Response({'error': str(e)}, status=status.HTTP_400_BAD_REQUEST)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Реклама

Обработка Webhooks от Stripe для подтверждения платежей

Для обработки Webhooks, вам потребуется создать endpoint, который будет получать уведомления от Stripe. Этот endpoint должен проверять подпись запроса для обеспечения безопасности.

# views.py

from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
import json

@csrf_exempt
def stripe_webhook(request):
    payload = request.body
    sig_header = request.META['HTTP_STRIPE_SIGNATURE']
    event = None

    try:
        event = stripe.Webhook.construct_event(
            payload,
            sig_header,
            settings.STRIPE_WEBHOOK_SECRET
        )
    except ValueError as e:
        # Invalid payload
        return HttpResponse(status=400)
    except stripe.error.SignatureVerificationError as e:
        # Invalid signature
        return HttpResponse(status=400)

    # Handle the event
    if event['type'] == 'checkout.session.completed':
        session = event['data']['object']

        # Fulfill the purchase...
        print(session)

    return HttpResponse(status=200)

Сохранение информации о платежах в базе данных

После получения Webhook-сообщения о завершении платежа, вы можете сохранить информацию о платеже в своей базе данных.

# models.py

from django.db import models

class Payment(models.Model):
    session_id = models.CharField(max_length=255)
    amount = models.IntegerField()
    currency = models.CharField(max_length=3)
    payment_status = models.CharField(max_length=20, default='pending')
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return f'Payment {self.session_id}'

Интеграция с Frontend и тестирование

Пример интеграции с React/Vue для отправки запросов на API

На frontend необходимо отправить POST-запрос на созданный API endpoint с данными о платеже.

// React example

import React, { useState } from 'react';
import axios from 'axios';

function PaymentForm() {
  const [amount, setAmount] = useState('');
  const [sessionId, setSessionId] = useState('');

  const handleSubmit = async (event) => {
    event.preventDefault();
    try {
      const response = await axios.post('/api/create-checkout-session/', { amount: parseInt(amount) });
      setSessionId(response.data.id);
      window.location.href = `https://checkout.stripe.com/checkout.js?session_id=${response.data.id}`
    } catch (error) {
      console.error(error);
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <label>
        Amount:
        <input type="number" value={amount} onChange={(e) => setAmount(e.target.value)} />
      </label>
      <button type="submit">Pay</button>
       {sessionId && <p>Session ID: {sessionId}</p>}
    </form>
  );
}

export default PaymentForm;

Тестирование платежной системы Stripe (Stripe Test Clock/ тестовые карты)

Stripe предоставляет инструменты для тестирования платежной системы, включая тестовые карты и Stripe Test Clock.

  • Тестовые карты: Используйте тестовые номера карт для имитации успешных и неудачных платежей.
  • Stripe Test Clock: Инструмент для тестирования подписок и других сценариев, связанных со временем.

Обработка ошибок и логирование

Важно предусмотреть обработку ошибок и логирование для отслеживания проблем и обеспечения стабильной работы системы.

import logging

logger = logging.getLogger(__name__)

try:
    checkout_session = stripe.checkout.Session.create(
        ...
    )
except Exception as e:
    logger.error(f'Error creating checkout session: {e}')

Заключение и дальнейшие шаги

Краткое резюме проделанной работы

В этой статье мы рассмотрели процесс интеграции Stripe с Django REST Framework, включая настройку Stripe, создание API endpoints, обработку Webhooks и интеграцию с frontend.

Советы по безопасности и оптимизации интеграции Stripe

  • Безопасность: Всегда проверяйте подпись Webhook-запросов от Stripe.
  • Оптимизация: Используйте асинхронные задачи (Celery) для обработки Webhooks и других ресурсоемких операций.
  • Мониторинг: Регулярно проверяйте логи и метрики для выявления проблем.

Полезные ресурсы и ссылки (документация Stripe, Django REST Framework)


Добавить комментарий