Online Resource 2: analysis scripts

Article: Digitally Enabled Accounts and Unsolicited Requests for Money: Exposure and Payment Response among Phone Owners in 75 Economies (Journal of Consumer Policy)

These scripts reproduce every table and figure in the article and in Online Resource 1 from the raw Global Findex 2025 microdata. The archive contains scripts only: no microdata, derived data or result files.

Data (not included; the licence does not permit redistribution)
1. Global Findex 2025 microdata, WLD_2024_FINDEX_v02_M, from the World Bank Microdata Library, https://doi.org/10.48529/bk9n-8r43. Save the Stata file as data/findex_microdata_2025_labelled_update112425.dta.
2. World Bank historical income classification (OGHIST, release 2025-10-07). Save it as data/WB_income_classification_OGHIST_2025_10_07.xlsx.

Software (versions used for the reported results)
Python 3.13.16; pandas 3.0.5; numpy 2.5.3; scipy 1.18.1; statsmodels 0.15.0; pyreadstat 1.3.6; openpyxl 3.1.5; matplotlib 3.11.2.

Running: two steps
Step 1. cd scripts; ./run_all.sh
  Writes result tables to out/ and figures to figures/.
Step 2. (in scripts/) python3 14_bootstrap999.py 999 > ../out/log_14_bootstrap999.txt 2>&1
  About 90 minutes. Step 1 alone does NOT produce the 999-replication economy-cluster bootstrap (seed 20261009) behind Table 4 of the article, the bootstrap columns of Online Resource 1, Tables A8 and A8b, and the bootstrap p-value for the difference between margins. These come from out/T13_bootstrap999_summary.csv, written by this step.

Scripts
lib.py                          survey-weighted logit and linear models with economy-clustered sandwich variance, standardised risks
01_prepare.py                   variable construction from the raw file; sample flow (T0)
02_exposure.py                  exposure models and sensitivity (T1)
03_conversion.py                conversion models, phone-lock diagnostics, wild cluster bootstrap (T2)
03b_selection.py                bivariate probit with sample selection (T2d; reported as uninformative)
04_consequences.py              dormancy, distrust and account use (T3)
05_summary.py                   moderation analyses and multiple testing in the analysis plan (T4, T5)
06_core_robustness.py           standardised risks at three margins, Oster bounds, E-values (T6)
07_mechanism.py                 account type and intensity at conversion (T7)
08_robustness_checks.py         payment capacity, weighting, country meta-analysis, collider simulation, minimum detectable effects, missing data, subgroups, liquidity (T8)
09_additional.py                stacked estimating equations, descriptive profile, population totals, full model tables (T9)
10_figures.py                   Figs. 1-4 and S1-S6 (run after 15_further_checks.py)
11_descriptives.py              Table 1 (T10)
12_paper_multiple_testing.py    Holm and Benjamini-Hochberg adjustment for the article's hypotheses (T11)
14_bootstrap999.py              999-replication economy-cluster bootstrap: margin comparison, two-part g-formula and alternative decompositions (T13; step 2)
15_further_checks.py            account type at three margins, remittances, population weights without India, coefficient-stability grid, Cinelli-Hazlett for conversion, wide collider simulation, risk ratios for robustness checks (T14a-T14g)
15b_remit_interaction.py        account premium by remittance use with interaction test (T14h)

Script numbers 13 and 09b are not used: they held earlier, shorter bootstraps that 14_bootstrap999.py replaces.

Some scripts also run analyses from the internal analysis plan (not preregistered) that the article does not use as evidence; Online Resource 1, Table A12, reports all of them, and Table A0 states the role of each analysis.

Variable names
Internal names differ from the article's terms. loss_cond is the payment response among targeted respondents (conversion; item con22) and loss_uncond is overall payment among all phone owners. They record whether money was sent in response to an unsolicited request, not a verified loss. Likewise, "total loss" in model labels means overall payment.
