pip install kvellimport os
import kvell
client = kvell.Client(
api_key=os.environ["KVELL_API_KEY"],
secret_key=os.environ["KVELL_SECRET_KEY"],
environment="sandbox", # switch to "production" when you go live
)
import os
import kvell
client = kvell.Client(
api_key=os.environ["KVELL_API_KEY"],
secret_key=os.environ["KVELL_SECRET_KEY"],
environment="sandbox",
)
# Amounts are always integers in kuruş (1/100 TRY) — 15000 = 150.00 TRY
session = client.payment_sessions.create(
transaction_id="ORDER-2026-001",
amount=15000,
currency="TRY",
description="Order #1234",
return_url="https://merchant.example.com/return",
)
print(f"Redirect the buyer to: {session.checkout_url}")
import os
import kvell
from kvell import KvellError
client = kvell.Client(
api_key=os.environ["KVELL_API_KEY"],
secret_key=os.environ["KVELL_SECRET_KEY"],
environment="sandbox",
)
def charge_card():
try:
payment = client.payments.charge(
transaction_id="ORDER-2026-001",
amount=15000, # kuruş
currency="TRY",
card_token="tok_9f8e7d6c5b4a",
)
print(f"Captured payment {payment.payment_id}")
return payment
except KvellError as err:
if err.code == "KVELL-PAY-4001":
print(f"Card declined (requestId={err.request_id})")
elif err.code == "KVELL-GW-1002":
print(f"Signature invalid, check your secret key (requestId={err.request_id})")
else:
print(f"Kvell error {err.code} (requestId={err.request_id})")
raise
import hashlib
import hmac
import os
from flask import Flask, request
app = Flask(__name__)
seen_event_ids = set() # swap for Redis/DB in production
@app.post("/webhooks/kvell")
def kvell_webhook():
signature_header = request.headers.get("X-Kvell-Signature", "")
event_id = request.headers.get("X-Kvell-Event-Id", "")
raw_body = request.get_data() # raw bytes, never the parsed JSON
secret = os.environ["KVELL_WEBHOOK_SECRET"].encode()
digest = hmac.new(secret, raw_body, hashlib.sha256).hexdigest()
expected = "sha256=" + digest
if not hmac.compare_digest(signature_header, expected):
return "invalid signature", 401
if event_id in seen_event_ids:
return "duplicate", 200
seen_event_ids.add(event_id)
event = request.get_json()
if event["eventType"] == "payment.captured":
pass # fulfil the order for event["payload"]["paymentId"] asynchronously
return "ok", 200