Phone Insights API

Phone Insights API

This API can parse, format and find phone numbers in text documents for any phone number worldwide.

These are the endpoints:

Endpoint /parse

Given a phone number with an international prefix, or if you prefer by specifying the ISO country code, and the national phone number instead, we can tell you:

  • number_type: One of the following: FIXED, MOBILE, VOIP, SHORT_NUMBER, PREMIUM, TOLL_FREE, PAGER, etc.
  • location: Where available by prefix.
  • phone_number_e164: Phone number in E164. Perfect to be saved in a database in a standard way.
  • carrier: In countries where blocks of numbers are assigned to carriers. Note that if portability is available in the country, we will return the original carrier.
  • is_valid_number: Using the length, format and prefixes against our 100Mbytes+ database of phone numbers we can asses the validity of the phones. E.g. we can detect fake US numbers if the prefixes don’t exist.
  • country_code_iso: Two letter ISO country code for the phone number.
  • We also give other auxiliary fields such as: number_of_leading_zeros, national_number, etc. If you need more information returned, contact us!

Example request:

curl -X POST --include '' \
  -H 'X-Mashape-Key: {my-mashape-key}' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  --data-binary '{"phone_number":"+34626475849","country_code":"ES"}'

That returns:

  "country_code": 34,
  "country_code_iso": "ES",
  "location": "Spain",
  "location_latitude": 40.0028028,
  "location_longitude": -4.003104,
  "national_number": 626475849,
  "number_of_leading_zeros": null,
  "number_type": "MOBILE",
  "is_valid_number": true,
  "carrier": "Movistar",
  "phone_number_e164": "+34626475849"


Endpoint /format

Given a phone number with an international prefix, or if you prefer by specifying the ISO country code, and the national phone number instead, we can tell you:

  • national: phone number in national format, e.g. (415) 498-8739
  • international: phone number in international format, e.g. +1 (415) 498-8739
  • E164: phone number in E164 format, e.g. +14154988739
  • RFC3966: phone number in E164 format, e.g. tel:+14154988739

Example request:

curl -X POST --include '' \
  -H 'X-Mashape-Key: {my-mashape-key}' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  --data-binary '{"phone_number":"+34626475849","country_code":"ES"}'


  "national": "626 47 58 49",
  "international": "+34 626 47 58 49",
  "E164": "+34626475849",
  "RFC3966": "tel:+34-626-47-58-49"

Endpoint /find-numbers-in-text Endpoint

Given a text document (max. 512 characters), we can find all phone numbers in it. E.g. for the text: Hey, the office's phone number is (510) 765-9845, my personal one is 4157653478. We will return the begin and end character position for both phone numbers, along with a E164 formatted version of each. We can find phone numbers, even if the format used in the document differs.

curl -X POST --include '' \
  -H 'X-Mashape-Key: {my-mashape-key}' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  --data-binary '{"text":"Hello, call me at 4154785647 or at (510) 675 8976 if it's after 11PM","country_code":"US"}'


  "matches": [
      "start": 18,
      "end": 28,
      "phone_number": "+14154785647"
      "start": 35,
      "end": 49,
      "phone_number": "+15106758976"

If you want to try it, head to mashape: The API is completely free!

Posted by admin in API, phone, python, 0 comments

Tennis API

I published a tennis API on

This API has methods to query all tennis matches on the ATP since 1968,  along with players and qualifications. Dynamic filtering, sorting and pagination of the results are allowed.

Example request to get matches played on Clay that lasted over 350 minutes (almost 6 hours!):

curl --get --include '{"minutes":">350", "surface": "Clay"}' \
  -H 'X-Mashape-Key: {mashape_key}' \
  -H 'Accept: application/json
  "_items": [
      "id": 125145,
      "tourney_id": "2004-520",
      "tourney_name": "Roland Garros",
      "surface": "Clay",
      "draw_size": 128,
      "tourney_level": "G",
      "tourney_date": "2004-05-24",
      "match_num": 61,
      "winner_id": 102148,
      "winner_seed": 0,
      "winner_entry": "",
      "winner_name": "Fabrice Santoro",
      "winner_hand": "R",
      "winner_ht": 178,
      "winner_ioc": "FRA",
      "winner_age": 31.4552,
      "winner_rank": 58,
      "winner_rank_points": 662,
      "loser_id": 103096,
      "loser_seed": 32,
      "loser_entry": "",
      "loser_name": "Arnaud Clement",
      "loser_hand": "R",
      "loser_ht": 173,
      "loser_ioc": "FRA",
      "loser_age": 26.4339,
      "loser_rank": 33,
      "loser_rank_points": 1005,
      "score": "6-4 6-3 6-7(5) 3-6 16-14",
      "best_of": 5,
      "round": "R128",
      "minutes": 393,
      "winner_ace": "22",
      "w_df": 2,
      "w_svpt": 229,
      "w_1stIn": 108,
      "w_1stWon": 77,
      "w_2ndWon": 60,
      "w_SvGms": 36,
      "w_bpSaved": 13,
      "w_bpFaced": 22,
      "l_ace": 10,
      "l_df": 9,
      "l_svpt": 234,
      "l_1stIn": 121,
      "l_1stWon": 84,
      "l_2ndWon": 52,
      "l_SvGms": 34,
      "l_bpSaved": 17,
      "l_bpFaced": 27,
      "_created": "Thu, 01 Jan 1970 00:00:00 GMT",
      "_updated": "Thu, 01 Jan 1970 00:00:00 GMT",
      "_etag": "d6e3dcd73f0a27191ce602f0d537e697a022e690",
      "_links": {
        "self": {
          "title": "Atp_match",
          "href": "atp_match/125145"
      "id": 164617,
      "tourney_id": "2017-0308",
      "tourney_name": "Munich",
      "surface": "Clay",
      "draw_size": 32,
      "tourney_level": "A",
      "tourney_date": "2017-05-01",
      "match_num": 297,
      "winner_id": 111202,
      "winner_seed": 0,
      "winner_entry": "",
      "winner_name": "Hyeon Chung",
      "winner_hand": "R",
      "winner_ht": 0,
      "winner_ioc": "KOR",
      "winner_age": 20.95,
      "winner_rank": 78,
      "winner_rank_points": 659,
      "loser_id": 105373,
      "loser_seed": 0,
      "loser_entry": "",
      "loser_name": "Martin Klizan",
      "loser_hand": "L",
      "loser_ht": 190,
      "loser_ioc": "SVK",
      "loser_age": 27.8056,
      "loser_rank": 53,
      "loser_rank_points": 880,
      "score": "6-4 3-6 6-2",
      "best_of": 3,
      "round": "QF",
      "minutes": 987,
      "winner_ace": "4",
      "w_df": 2,
      "w_svpt": 81,
      "w_1stIn": 47,
      "w_1stWon": 36,
      "w_2ndWon": 15,
      "w_SvGms": 13,
      "w_bpSaved": 4,
      "w_bpFaced": 6,
      "l_ace": 8,
      "l_df": 4,
      "l_svpt": 95,
      "l_1stIn": 49,
      "l_1stWon": 28,
      "l_2ndWon": 27,
      "l_SvGms": 14,
      "l_bpSaved": 8,
      "l_bpFaced": 12,
      "_created": "Thu, 01 Jan 1970 00:00:00 GMT",
      "_updated": "Thu, 01 Jan 1970 00:00:00 GMT",
      "_etag": "3e4d5985b601dad5b0229b881b6a0fe52aa06af0",
      "_links": {
        "self": {
          "title": "Atp_match",
          "href": "atp_match/164617"


Posted by admin in API, data-science, 0 comments
Tablifyme API

Tablifyme API

I created an API that creates a text table from a JSON array. Useful to send tables of data over email, Slack or Markdown.

The API is available on Mashape:


curl -X POST --include '' \
-H 'X-Mashape-Key: My-Secret-key' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
--data-binary '{"body":[[1,2,3],[4,"test",6]],"header":["Y","A","B"]}'


|  Y  |  A   |  B  |
|  1  |  2   |  3  |
|  4  | test |  6  |



Posted by admin in API, data-science, 0 comments
Choropleth: percentage of foreigners by US county

Choropleth: percentage of foreigners by US county

Building maps is very easy with Folium. I got my hands on some data from the US Census, specifically, the foreign born population and total population per US county.

To plot it, first download the CSV from the  2011-2015 American Community Survey 5-Year Estimates.

import os
import folium
import pandas as pd

# Load data
data = pd.read_csv('data.csv')

# Add column with ratio of foreign born vs total pop.
data['ratio_foreign_born_vs_total_population'] = 100 * data['Estimate; Foreign born:'] / data['Estimate; Total:']

# Create map
map_1 = folium.Map(location=[39, -96], zoom_start=4)
high_res_county_geo = os.path.relpath('gz_2010_us_050_00_500k.json') # from

# Add choropleth layer
 columns=['Id', 'ratio_foreign_born_vs_total_population'],
 legend_name='Percentage Foreigners(%)',
 threshold_scale=[0, 5, 10, 15, 20, 25]


# Save as index.html'index.html')

The result:

Posted by admin in data-science, python, 0 comments
Saïgon on iPhone 6 iOS 10.2.1

Saïgon on iPhone 6 iOS 10.2.1

Saigon’s Jailbreak is now on beta 2r1, and it promises to jailbreak iPod Touch 6 (10.2.1), iPhone SE (10.2.1), iPhone 6/Plus (10.2.1), iPhone 6s/Plus (10.2.1), iPad Mini 4 (10.2.1) (Not tested), iPad Air 2 (10.2.1). I have an iPhone 6 on 10.2.1 and decided to give it a try.

Download Cydia impactor from

Download Saigon.ipa from

Login into your and create an app specific password.

Open Cydia Impactor and Drag and drop the Saigon.ipa into it. You will be prompted to enter your email (the same one you used at appleid) and your password, for this one, use the one time password you just create it.

Saigon should now be installed on your phone. Open it and you should see a Jailbreak button. Note that because this is a beta 2, and because the vulnerability that is based on is random, the jailbreak will probably fail a few times before it succeeds.

In my case, despite having a compatible device iPhone 6 on 10.2.1, after installing Saigon I was getting a message with Device Not Compatible. To solve this, I cloned the repo with Saigon’s code and compiled the .ipa myself:

~/D/Code ❯❯❯ git clone
~/D/Code ❯❯❯ ./ was failing with some cryptic errors, I found that xcrun –sdk iphoneos –show-sdk-path was using the SDK for iOS 11, instead, I manually run the commands:

~/D/Code ❯❯❯ $(which xcodebuild) clean build CODE_SIGNING_REQUIRED=NO CODE_SIGN_IDENTITY="" -sdk /Applications/ -arch arm64

~/D/Code ❯❯❯ mv build/Release-iphoneos/ saï
~/D/Code ❯❯❯ zip -r9 Saïgon.ipa Payload/saï

I then impacted this IPA on my device, and magically my device was now supported! 🙂 For your convenience, this is the .ipa I created.


Posted by admin in apple, phone, 0 comments
Everything that’s wrong with the new iPhone 8

Everything that’s wrong with the new iPhone 8

Although a heavy Mac Book user and lover, I had been away from Apple phones, I saw them as more restricted and expensive versions of their Android counterparts but that changed recently when my company gave me a corporate iPhone 8 Plus 256Gb.

I’ve used the phone for roughly two weeks and I would like to comment on everything that I came to realize it’s wrong with it.

Lightning Port

Why in the hell did Apple not substitute their proprietary 1-star lightning cable for the superior USB-C?  This is extremely annoying, the whole industry is moving towards USB-C as a standard, it’s de facto for new Android phones, and contradictory enough, for the new Mac Books. Even legislators such as the European Union are looking into forcing manufacturers that want to sell phones inside the EU to adopt a common charger, to reduce e-waste. But Apple has different plans…

Yep, that’s a solid 1-star average.

Having a lighting cable means that I need to carry two chargers now, one for my Mac (USB-C) and one for my iPhone (lightning), before, with my Android, my Mac charger would suffice, as I could charge both with it.

Also, connecting my Mac and iPhone out of the box is now impossible. You are forced to buy a USB-C to USB extension for your Mac.

Hey, at least this one is 2-stars!


I was actually excited before receiving the iPhone 8, I thought I’ll have some of those Bluetooth earpods that everybody seems to love, or at least they seem to carry around with impunity. So there I am, opening the iPhone 8 Plus, a 1000$+ phone in California, when I discover the uncomfortable truth.

Apple has not included the Bluetooth earpods, instead, they have included wired earbuds. But it get’s even worse, because of the lack of a jack connector, the earbuds are lighting too, which means that you can only use them on your phone. Now, if you travel with your laptop and phone, you have to bring two sets of earpods. And yes, to add to the inconsistency, the Mac Book Pro latest model does have a jack connector.

Those will not work anywhere else, not even on your Mac.

At least two things that they could have done to remedy the situation, first, if I am paying more than 1K$ for a phone that doesn’t have a jack, don’t nickel and dime me for extra Bluetooth earbuds, include them “for free”. Otherwise, put a USB-C connector on the iPhone, and include wired earbuds, that at least work on my computer and phone.

The Design

Supposedly Apple was at least good at this one, but I am starting the hesitate. The iPhone 8 design is almost an exact copy of it’s much older brother iPhone 6, and time is starting to show, those huge bezels at the top and bottom are not cool anymore, the home button, even if maintained, could have been squeezed as some Androids have done to increase screen real estate, or even placed behind.

The design is starting to show it’s age.

The glass back is cool but is a fingerprint magnet, and dropping it is a liability. Haptic feedback and force touch are in my opinion underutilized features, I barely use them, and including them makes for a thicker phone.

Overall, it feels like Apple didn’t put much time or effort into this one. They were focused on the iPhone X that got all the media attention, and for the iPhone 8 they basically took the 7 and put in a slightly better processor and a higher price tag. For the foreseeable future, I will stick to Android.





Posted by admin in apple, 1 comment

[MAC] Install matplotlib basemap on virtualenv

I am using Python3.6 and MacOS 10.13.2(Beta) but should work with similar setups.

First create and activate your virtual environment, by default mine is created on top of Python3.6.

~ ❯❯❯ mkvirtualenv basemap-virtualenv
Installing setuptools, pip, wheel...done.
(basemap-virtualenv) ~ ❯❯❯ cd Desktop
(basemap-virtualenv) ~/Desktop ❯❯❯ curl -o basemap-v1.1.0.tar.gz

Note that I am using the latest version 1.1.0 as of the time of writing this, but you should use the latest available on

Let’s start the installation

(basemap-virtualenv) ~/Desktop ❯❯❯ tar -xvf basemap-v1.1.0.tar.gz
(basemap-virtualenv) ~/Desktop ❯❯❯ cd basemap-1.1.0/geos-3.3.3/
(basemap-virtualenv) ~/D/b/geos-3.3.3 ❯❯❯ export GEOS_DIR=/usr/local
(basemap-virtualenv) ~/D/b/geos-3.3.3 ❯❯❯ ./configure --prefix=$GEOS_DIR
(basemap-virtualenv) ~/D/b/geos-3.3.3 ❯❯❯ make; make install

After this geos library is installed, let’s jump onto installing basemap.

(basemap-virtualenv) ~/D/basemap-1.1.0 ❯❯❯ pip install numpy
(basemap-virtualenv) ~/D/basemap-1.1.0 ❯❯❯ pip install pyproj
(basemap-virtualenv) ~/D/basemap-1.1.0 ❯❯❯ pip install pyshp

(basemap-virtualenv) ~/D/basemap-1.1.0 ❯❯❯ python install
customize UnixCCompiler
customize UnixCCompiler using build_ext
building '_geoslib' extension
compiling C sources
C compiler: clang -Wno-unused-result -Wsign-compare -Wunreachable-code -fno-common -dynamic -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes

compile options: '-I/usr/local/include -I['/Users/myself/.virtualenvs/basemap-virtualenv/lib/python3.6/site-packages/numpy/core/include'] -I/Users/myself/.virtualenvs/basemap-virtualenv/lib/python3.6/site-packages/numpy/core/include -I/usr/local/Cellar/python3/3.6.2/Frameworks/Python.framework/Versions/3.6/include/python3.6m -c'
clang: src/_geoslib.c
zsh:1: no matches found: -I[/Users/myself/.virtualenvs/basemap-virtualenv/lib/python3.6/site-packages/numpy/core/include]
zsh:1: no matches found: -I[/Users/myself/.virtualenvs/basemap-virtualenv/lib/python3.6/site-packages/numpy/core/include]
error: Command "clang -Wno-unused-result -Wsign-compare -Wunreachable-code -fno-common -dynamic -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I/usr/local/include -I['/Users/myself/.virtualenvs/basemap-virtualenv/lib/python3.6/site-packages/numpy/core/include'] -I/Users/myself/.virtualenvs/basemap-virtualenv/lib/python3.6/site-packages/numpy/core/include -I/usr/local/Cellar/python3/3.6.2/Frameworks/Python.framework/Versions/3.6/include/python3.6m -c src/_geoslib.c -o build/temp.macosx-10.12-x86_64-3.6/src/_geoslib.o -MMD -MF build/temp.macosx-10.12-x86_64-3.6/src/_geoslib.o.d" failed with exit status 1

As we can see, the installation out of the box is failing. More specifically, the command

clang -Wno-unused-result -Wsign-compare -Wunreachable-code -fno-common -dynamic -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes compile options: '-I/usr/local/include -I['/Users/myself/.virtualenvs/basemap-virtualenv/lib/python3.6/site-packages/numpy/core/include'] ...

The reason lies in a bug on  If you read the error, you will see how we are trying to include (-I) a path, but instead, we are passing a python array with a single string inside.  To fix this go to this line:

geos_include_dirs = [os.path.join(GEOS_dir,'include'),inc_dirs]

and change it to:

geos_include_dirs = [os.path.join(GEOS_dir,'include'),inc_dirs[0]]

After that python install succeeds.

Posted by admin in python, 0 comments Great affordable WordPress Hosting Great affordable WordPress Hosting

Web development stack

I’ve built quite a few websites for clients, friends, family and for myself too in the last few years, some examples are:, or this very blog. Over time, I’ve polished the tool and techniques, to speed up development, and to increase the quality. At this point my default and preferred architecture that I recommend to most clients is WordPress + Enfold theme. There are powerful reasons behind this choice:

  • WordPress is great. Used by ~27% of the top 10M websites, with a very rich plugin ecosystem, and a visual, intuitive, web based builder. It’s built on technologies that have passed the test of time: PHP and MySQL. The web interface allows non technical customers to make tweaks and additions if they are needed after the project is finished.
  • Enfold by Kriesi is one of the most popular WordPress themes out there, and rightfully so. Their intuitive UI makes it straightforward to create visually compelling websites. It comes with dozens of UI elements, including contact forms, google maps, and image sliders, and they are all personalizable.

I think the quality of the examples above prove the point. The clients were extremely happy with the result, and after 2-3 years, the websites still look sleek and responsive.



This is where the headaches begin. I started recommending my first clients to go with GoDaddy, the had made a name for themselves, their support was always available, and their cPanel web management, although far from perfect, got the job done. Finally, about the price, they weren’t so bad at the beginning, and they included some freebies such as Google Ads credit.

GoDaddy has however let me down in multiple occasions, so I have progressively pushed them down the list of recommended hosting solutions. My first problem with them were their continuous and unwarned price rises, we were paying no more than 20$ for hosting on the first year, but by the third, the bill was over 100$. They also have a very aggressive up-sale and cross-sale model, constantly and annoyingly suggesting you to buy their SSL certificate for 70$+ or to get a faster hosting (read next paragraph) for another 100$.

Secondly comes the speed, in case you don’t know, speed loading in a website is critical in this world of instant gratification, visitors don’t like waits; according to Kissmetrics, every second that passes before the web loads leads to a 7% decrease in conversions.  GoDaddy, in an attempt to cut costs, makes you share a server with hundreds if not thousands of other websites, reducing speed and responsiveness.

Lastly, they recently changed their support policy, you can’t email and are forced to call them. Their support team is helpful, but unfortunately they’ve been trained to try and sell you other services…

Getflywheel and WPEngine

These guys understand WordPress hosting: great infrastructure, free SSL certificates (they are free for them, so that makes sense), free backups and flawless user experience. I have tried both services, and really, they are good.

They have only one inconvenient: they are both alarmingly expensive. Their basic plans can set you back at 250$ per year, and it only goes up from there. Unfortunately, most people can’t justify that expense for a website with some dozen visitors per day.


This is where comes into the game. I’ve developed Fendera using the latest cloud computing technologies: Docker + Kubernetes. Kubernetes is legendary; created by Google as a way to ensure services such as YouTube or Gmail were available 99.99999% of the time and later released to the community. It’s not by chance that it integrates very nicely with Google Cloud, arguably one of the best cloud computing provider.

I wanted to break apart from how GoDaddy did things, and I wanted to stay close to Getflywheel or WPEngine but without forgetting about affordability. Our current plan sets you back at only 34$ per year, yet it comes with free SSL certificates, free weekly backups,  6Gb of SSD and a lot of horse power under Google Cloud’s hood. Moreover, thanks to Kubernetes we can guarantee great up times SLAs and ensure a safe and reliable service.

If you want to give it a try, please register at Questions or feedback are welcome!

Posted by admin in computer, docker, wordpress, 0 comments

WordPress Enfold YouTube video only displaying link

I had a problem recently on a website using WordPress and the Enfold theme. A YouTube video that was initially marked as private, but later updated to public (embeddable) was still only showing the link, and not the actual video player.

A previously private video but later publicly released was still showing as a link on the website.

Other videos however in the same page, where showing properly.

Other videos however, as this one in the image where showing properly.

Other videos, however, as this one in the image where showing properly.

It turns out that from reading here that WordPress does some caching and is not pulling the latest youtube change.

To fix the problem, connect to the MySQL client, and retrieve all pages with an embedded video:

mysql> SELECT * FROM wp_postmeta WHERE meta_key like '%_oembed%';

My results were something like this:

| meta_id | post_id | meta_key | meta_value |
| 306 | 86 | _oembed_5c3aff6d73f219 | {{unknown}} |
| 336 | 10 | _oembed_39378045d82af3 | {{unknown}} |
| 337 | 10 | _oembed_a26684b605680e | {{unknown}} |
| 354 | 86 | _oembed_af60fe80d2fe16 | <iframe src="></iframe>|
| 355 | 86 | _oembed_time_af60fe80d2fe16 | 1503662521 |
| 356 | 10 | _oembed_f4d0e4e5251dea | <iframe src="</iframe> |
| 357 | 10 | _oembed_time_f4d0e4e5251dea | 1503662579 |
| 359 | 71 | _oembed_time_a26684b605680e | 1503662615 |
| 385 | 138 | _oembed_f4d0e4e5251dea | <iframe src="</iframe> |
| 386 | 138 | _oembed_time_f4d0e4e5251dea | 1503777685 |
| 387 | 138 | _oembed_4c76e997d8b21a | {{unknown}} |
| 389 | 138 | _oembed_268d95c8d907aa | {{unknown}} |
| 391 | 138 | _oembed_time_a26684b605680e | 1505355944 |

I tried removing the offending meta_id, by issuing:

mysql> DELETE from wp_postmeta WHERE meta_key like '%_oembed%' and meta_value like '%OeiZNr24o7g%';

However that didn’t work when I refreshed the page, so I decided on the more radical solution:

mysql> DELETE from wp_postmeta WHERE meta_key like '%_oembed%';

That solved all my problems!

Posted by admin in wordpress, 0 comments

Python Stripe Signature Verification Error

Building a Django + Stripe integration today I kept hitting the SignatureVerificationError.

According to their webhook’s documentation, they recommend something like this:

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

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

  # Do something with event

  return HttpResponse(status=200)

I think would work fine with python2, but in my case the signature being generated never matched the expected signature hence triggering the exception stripe.error.SignatureVerificationError

The solution is to utf8 decode the payload, on line 3, change:

payload = request.body
payload = request.body.decode('utf-8')

That did the trick, hope it can save someone some time.

Posted by admin in python, stripe, 1 comment