{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# LiqPay API Notebook"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Setup"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Load environment variables and code autoreload plugin."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%load_ext autoreload\n",
    "%autoreload 2\n",
    "\n",
    "%load_ext dotenv\n",
    "%dotenv -o .env"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Imports"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from os import getenv\n",
    "from uuid import uuid4\n",
    "from pprint import pprint\n",
    "from datetime import datetime, timedelta\n",
    "from webbrowser import open_new_tab\n",
    "\n",
    "from liqpy.client import Client, AsyncClient\n",
    "from liqpy.api.exceptions import LiqPayException\n",
    "from liqpy.dev.testing import TestCard, gen_card_cvv, gen_card_expire\n",
    "from liqpy.dev.server import LiqpayServer"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Initialize client with public and private keys"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "client = Client()\n",
    "client"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Examples"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Forming a request to API"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "order_id = uuid4()\n",
    "order_id"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Encode request and decode it as callback"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "data, signature = client.encode(\n",
    "    action=\"pay\",\n",
    "    amount=1,\n",
    "    order_id=order_id,\n",
    "    description=\"Test Encoding\",\n",
    "    currency=\"USD\",\n",
    ")\n",
    "\n",
    "sep, end = \"\\n\", \"\\n\\n\"\n",
    "print(\"data:\", data, sep=sep, end=end)\n",
    "print(\"signature:\", signature, sep=sep, end=end)\n",
    "\n",
    "client.callback(data, signature)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Make payments"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "card_exp_month, card_exp_year = gen_card_expire(valid=True)\n",
    "card_cvv = gen_card_cvv()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Pay request with test card"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "order_id = uuid4()\n",
    "\n",
    "client.hold(\n",
    "    order_id=order_id,\n",
    "    amount=1,\n",
    "    currency=\"USD\",\n",
    "    description=\"Test Payment\",\n",
    "    card=TestCard.successful(),\n",
    "    card_exp_month=card_exp_month,\n",
    "    card_exp_year=card_exp_year,\n",
    "    card_cvv=card_cvv,\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "client.complete(order_id)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "order_id = uuid4()\n",
    "\n",
    "client.pay(\n",
    "    order_id=order_id,\n",
    "    amount=1,\n",
    "    currency=\"USD\",\n",
    "    description=\"Test Payment\",\n",
    "    card=TestCard.successful(),\n",
    "    card_exp_month=card_exp_month,\n",
    "    card_exp_year=card_exp_year,\n",
    "    card_cvv=card_cvv,\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Refund the payment"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "client.refund(order_id)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Get a payment status"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "client.status(order_id)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "add info to payment"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "client.data(order_id, info=\"Lorem Ipsum\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Failed payment"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "try:\n",
    "    card_exp_month, card_exp_year = gen_card_expire(valid=True)\n",
    "\n",
    "    client.pay(\n",
    "        order_id=uuid4(),\n",
    "        amount=1,\n",
    "        currency=\"USD\",\n",
    "        description=\"Test Payment\",\n",
    "        card=TestCard.failure(\"9859\"),\n",
    "        card_exp_month=card_exp_month,\n",
    "        card_exp_year=card_exp_year,\n",
    "        card_cvv=gen_card_cvv(),\n",
    "    )\n",
    "except LiqPayException as e:\n",
    "    print(e.code, e)\n",
    "    print(e.response)\n",
    "    pprint(e.details)\n",
    "    raise e"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Webhooks"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "action = \"subscribe\"\n",
    "order_id = uuid4()\n",
    "\n",
    "expire = timedelta(seconds=60)\n",
    "timeout = (expire + timedelta(seconds=10)).total_seconds()\n",
    "\n",
    "server_url = getenv(\"SERVER_URL\") or None\n",
    "server_url"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Test checkout callback"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "checkout_url = client.checkout(\n",
    "    action,\n",
    "    amount=1,\n",
    "    order_id=order_id,\n",
    "    description=f\"test {action} checkout\",\n",
    "    currency=\"USD\",\n",
    "    expired_date=expire,\n",
    "    # subscribe_date_start=timedelta(days=7),\n",
    "    subscribe_periodicity=\"month\",\n",
    "    # result_url=\"https://example.com/result\",\n",
    "    server_url=server_url,\n",
    ")\n",
    "\n",
    "print(\"checkout link\\n\", checkout_url)\n",
    "open_new_tab(checkout_url)\n",
    "\n",
    "if server_url is not None:\n",
    "    with LiqpayServer(client=client, timeout=timeout) as server:\n",
    "        pprint(server.handle_callback())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Recurring payments"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "order_id = uuid4()\n",
    "order_id"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Create subscription"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "client.subscribe(\n",
    "    amount=1,\n",
    "    order_id=order_id,\n",
    "    description=\"Test Subscribe\",\n",
    "    currency=\"USD\",\n",
    "    card=TestCard.successful(),\n",
    "    card_exp_month=card_exp_month,\n",
    "    card_exp_year=card_exp_year,\n",
    "    card_cvv=card_cvv,\n",
    "    subscribe_periodicity=\"month\",\n",
    "    subscribe_date_start=timedelta()\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Edit a recurring payment"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Cancel a recurring payment"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "client.status(order_id)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "client.unsubscribe(order_id)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Reports"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "date_to = datetime.now()\n",
    "date_from = date_to - timedelta(hours=1)\n",
    "print(\"from:\", date_from)\n",
    "print(\"to:\", date_to)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Get payments report"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "result = client.payments(date_from=date_from, date_to=date_to)\n",
    "print(\"count:\", len(result))\n",
    "# pprint(result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Reports in XML (Excel) format"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "xml_data = client.reports(date_from=date_from, date_to=date_to, format=\"xml\")\n",
    "\n",
    "with open(\"liqpay.xls\", \"w\", encoding=\"utf-16\") as f:\n",
    "    f.write(xml_data)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Reports in CSV format"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "csv_data = client.reports(date_from=date_from, date_to=date_to, format=\"csv\")\n",
    "\n",
    "with open(\"liqpay.csv\", \"w\", encoding=\"utf-16\") as f:\n",
    "    f.write(csv_data)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "parse csv reports using standard module"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from csv import DictReader\n",
    "from liqpy.models.report import Report\n",
    "\n",
    "reports = [Report.from_dict(item) for item in DictReader(csv_data.splitlines())]\n",
    "pprint(reports[0])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "parse csv reports using pandas"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# !pip install pandas\n",
    "from io import StringIO\n",
    "from liqpy.pandas import read_liqpay_csv, ID_TYPE\n",
    "\n",
    "df = read_liqpay_csv(StringIO(csv_data))\n",
    "df.dtypes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df.describe(include=\"number\", exclude=ID_TYPE)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df.describe(include=\"category\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "venv",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
