chore: prepare app store submission (screenshots, metadata, privacy details) (#1905)
@ -116,7 +116,7 @@ jobs:
|
|||||||
match_type: 'adhoc'
|
match_type: 'adhoc'
|
||||||
provisioning_profile_name: 'match AdHoc org.mifospay'
|
provisioning_profile_name: 'match AdHoc org.mifospay'
|
||||||
firebase_app_id: '1:728434912738:ios:86a7badfaed88b841a1dbb'
|
firebase_app_id: '1:728434912738:ios:86a7badfaed88b841a1dbb'
|
||||||
metadata_path: './fastlane/metadata'
|
metadata_path: './fastlane/metadata/ios'
|
||||||
use_cocoapods: true # <-- Set to true if using CocoaPods integration for KMP
|
use_cocoapods: true # <-- Set to true if using CocoaPods integration for KMP
|
||||||
shared_module: ':cmp-shared' # <-- Gradle path to your shared KMP module (e.g., :shared)
|
shared_module: ':cmp-shared' # <-- Gradle path to your shared KMP module (e.g., :shared)
|
||||||
distribute_ios_firebase: ${{ inputs.distribute_ios_firebase }}
|
distribute_ios_firebase: ${{ inputs.distribute_ios_firebase }}
|
||||||
|
|||||||
271
.github/workflows/sync-dirs.yaml
vendored
Normal file
@ -0,0 +1,271 @@
|
|||||||
|
name: Sync CMP Directories
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
upstream:
|
||||||
|
description: 'Upstream repository to sync directories from'
|
||||||
|
default: 'https://github.com/openMF/kmp-project-template.git'
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
schedule:
|
||||||
|
- cron: '0 0 * * 1'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
sync-directories:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
ref: dev
|
||||||
|
|
||||||
|
- name: Setup Git config
|
||||||
|
run: |
|
||||||
|
git config --global user.name "github-actions[bot]"
|
||||||
|
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||||
|
|
||||||
|
- name: Add upstream remote and fetch
|
||||||
|
run: |
|
||||||
|
git remote add upstream ${{ inputs.upstream }} || true
|
||||||
|
git fetch upstream || exit 1
|
||||||
|
|
||||||
|
- name: Check upstream/dev exists
|
||||||
|
run: |
|
||||||
|
if ! git rev-parse --verify upstream/dev >/dev/null 2>&1; then
|
||||||
|
echo "Error: upstream/dev branch does not exist"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Create and checkout temporary branch
|
||||||
|
run: |
|
||||||
|
TEMP_BRANCH="temp-sync-branch-${{ github.run_number }}"
|
||||||
|
git checkout -b "$TEMP_BRANCH" upstream/dev || exit 1
|
||||||
|
echo "TEMP_BRANCH=$TEMP_BRANCH" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Sync directories and files
|
||||||
|
run: |
|
||||||
|
# Declare directories and files to sync
|
||||||
|
DIRS=(
|
||||||
|
"cmp-android"
|
||||||
|
"cmp-desktop"
|
||||||
|
"cmp-ios"
|
||||||
|
"cmp-web"
|
||||||
|
"cmp-shared"
|
||||||
|
"core-base"
|
||||||
|
"build-logic"
|
||||||
|
"fastlane"
|
||||||
|
"scripts"
|
||||||
|
"config"
|
||||||
|
".github"
|
||||||
|
".run"
|
||||||
|
)
|
||||||
|
|
||||||
|
FILES=(
|
||||||
|
"Gemfile"
|
||||||
|
"Gemfile.lock"
|
||||||
|
"ci-prepush.bat"
|
||||||
|
"ci-prepush.sh"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Define exclusions
|
||||||
|
declare -A EXCLUSIONS=(
|
||||||
|
["cmp-android"]="src/main/res dependencies src/main/ic_launcher-playstore.png google-services.json"
|
||||||
|
["cmp-web"]="src/jsMain/resources src/wasmJsMain/resources"
|
||||||
|
["cmp-desktop"]="icons"
|
||||||
|
["cmp-ios"]="iosApp/Assets.xcassets"
|
||||||
|
["root"]="secrets.env"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Function to check if path should be excluded
|
||||||
|
should_exclude() {
|
||||||
|
local dir=$1
|
||||||
|
local path=$2
|
||||||
|
|
||||||
|
# Check for root exclusions
|
||||||
|
if [[ "$dir" == "." && -n "${EXCLUSIONS["root"]}" ]]; then
|
||||||
|
local root_excluded_paths=(${EXCLUSIONS["root"]})
|
||||||
|
for excluded in "${root_excluded_paths[@]}"; do
|
||||||
|
if [[ "$path" == *"$excluded"* ]]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check directory-specific exclusions
|
||||||
|
if [[ -n "${EXCLUSIONS[$dir]}" ]]; then
|
||||||
|
local excluded_paths=(${EXCLUSIONS[$dir]})
|
||||||
|
for excluded in "${excluded_paths[@]}"; do
|
||||||
|
if [[ "$path" == *"$excluded"* ]]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to preserve excluded paths
|
||||||
|
preserve_excluded() {
|
||||||
|
local dir=$1
|
||||||
|
if [[ -n "${EXCLUSIONS[$dir]}" ]]; then
|
||||||
|
local excluded_paths=(${EXCLUSIONS[$dir]})
|
||||||
|
for excluded in "${excluded_paths[@]}"; do
|
||||||
|
local full_path="$dir/$excluded"
|
||||||
|
if [[ -e "$full_path" ]]; then
|
||||||
|
echo "Preserving excluded path: $full_path"
|
||||||
|
local temp_path="temp_excluded/$full_path"
|
||||||
|
mkdir -p "$(dirname "$temp_path")"
|
||||||
|
cp -r "$full_path" "$(dirname "$temp_path")"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to restore excluded paths
|
||||||
|
restore_excluded() {
|
||||||
|
local dir=$1
|
||||||
|
if [[ -n "${EXCLUSIONS[$dir]}" ]]; then
|
||||||
|
local excluded_paths=(${EXCLUSIONS[$dir]})
|
||||||
|
for excluded in "${excluded_paths[@]}"; do
|
||||||
|
local full_path="$dir/$excluded"
|
||||||
|
local temp_path="temp_excluded/$full_path"
|
||||||
|
if [[ -e "$temp_path" ]]; then
|
||||||
|
echo "Restoring excluded path: $full_path"
|
||||||
|
mkdir -p "$(dirname "$full_path")"
|
||||||
|
rm -rf "$full_path"
|
||||||
|
cp -r "$temp_path" "$(dirname "$full_path")"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to preserve root-level excluded files
|
||||||
|
preserve_root_files() {
|
||||||
|
if [[ -n "${EXCLUSIONS["root"]}" ]]; then
|
||||||
|
local excluded_paths=(${EXCLUSIONS["root"]})
|
||||||
|
for excluded in "${excluded_paths[@]}"; do
|
||||||
|
if [[ -e "$excluded" ]]; then
|
||||||
|
echo "Preserving root-level excluded file: $excluded"
|
||||||
|
mkdir -p "temp_excluded/root"
|
||||||
|
cp -r "$excluded" "temp_excluded/root/"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to restore root-level excluded files
|
||||||
|
restore_root_files() {
|
||||||
|
if [[ -n "${EXCLUSIONS["root"]}" ]]; then
|
||||||
|
local excluded_paths=(${EXCLUSIONS["root"]})
|
||||||
|
for excluded in "${excluded_paths[@]}"; do
|
||||||
|
if [[ -e "temp_excluded/root/$excluded" ]]; then
|
||||||
|
echo "Restoring root-level excluded file: $excluded"
|
||||||
|
cp -r "temp_excluded/root/$excluded" "./"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create temp directory for exclusions
|
||||||
|
mkdir -p temp_excluded
|
||||||
|
|
||||||
|
# Preserve root-level exclusions before sync
|
||||||
|
preserve_root_files
|
||||||
|
|
||||||
|
# Switch to dev branch
|
||||||
|
git checkout dev
|
||||||
|
|
||||||
|
# Sync directories
|
||||||
|
for dir in "${DIRS[@]}"; do
|
||||||
|
if [ ! -d "$dir" ]; then
|
||||||
|
echo "Creating $dir..."
|
||||||
|
mkdir -p "$dir"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Preserve excluded paths before sync
|
||||||
|
if [[ -d "$dir" ]]; then
|
||||||
|
preserve_excluded "$dir"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Syncing $dir..."
|
||||||
|
git checkout "${{ env.TEMP_BRANCH }}" -- "$dir" || exit 1
|
||||||
|
|
||||||
|
# Restore excluded paths after sync
|
||||||
|
restore_excluded "$dir"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Sync files
|
||||||
|
for file in "${FILES[@]}"; do
|
||||||
|
dir=$(dirname "$file")
|
||||||
|
if ! should_exclude "$dir" "$file"; then
|
||||||
|
echo "Syncing $file..."
|
||||||
|
git checkout "${{ env.TEMP_BRANCH }}" -- "$file" || true
|
||||||
|
else
|
||||||
|
echo "Skipping excluded file: $file"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Restore root-level excluded files
|
||||||
|
restore_root_files
|
||||||
|
|
||||||
|
# Cleanup temp directory
|
||||||
|
rm -rf temp_excluded
|
||||||
|
|
||||||
|
- name: Clean up temporary branch
|
||||||
|
if: always()
|
||||||
|
run: git branch -D "${{ env.TEMP_BRANCH }}" || true
|
||||||
|
|
||||||
|
- name: Check for changes
|
||||||
|
id: check_changes
|
||||||
|
run: |
|
||||||
|
if [[ -n "$(git status --porcelain)" ]]; then
|
||||||
|
echo "has_changes=true" >> $GITHUB_OUTPUT
|
||||||
|
else
|
||||||
|
echo "has_changes=false" >> $GITHUB_OUTPUT
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Create Pull Request
|
||||||
|
if: steps.check_changes.outputs.has_changes == 'true'
|
||||||
|
uses: peter-evans/create-pull-request@v7
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.PAT_TOKEN }}
|
||||||
|
commit-message: "chore: Sync directories and files from upstream"
|
||||||
|
title: "chore: Sync directories and files from upstream"
|
||||||
|
body: |
|
||||||
|
Automated sync of directories and files from upstream repository.
|
||||||
|
|
||||||
|
Changes included in this sync:
|
||||||
|
|
||||||
|
Directories:
|
||||||
|
- cmp-android (excluding src/main/res, dependencies, ic_launcher-playstore.png, google-services.json)
|
||||||
|
- cmp-desktop (excluding icons)
|
||||||
|
- cmp-ios (excluding iosApp/Assets.xcassets)
|
||||||
|
- cmp-web (excluding src/jsMain/resources, src/wasmJsMain/resources)
|
||||||
|
- cmp-shared
|
||||||
|
- build-logic
|
||||||
|
- fastlane
|
||||||
|
- scripts
|
||||||
|
- config
|
||||||
|
- .github
|
||||||
|
- .run
|
||||||
|
|
||||||
|
Files:
|
||||||
|
- Gemfile
|
||||||
|
- Gemfile.lock
|
||||||
|
- ci-prepush.bat
|
||||||
|
- ci-prepush.sh
|
||||||
|
|
||||||
|
Root-level exclusions:
|
||||||
|
- secrets.env
|
||||||
|
|
||||||
|
Workflow run: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||||||
|
branch: sync-dirs-${{ github.run_number }}
|
||||||
|
delete-branch: true
|
||||||
|
labels: |
|
||||||
|
sync
|
||||||
|
automated pr
|
||||||
|
base: dev
|
||||||
@ -353,8 +353,8 @@
|
|||||||
baseConfigurationReference = E5D357E5C5AAADD27F979C77 /* Pods-iosApp.debug.xcconfig */;
|
baseConfigurationReference = E5D357E5C5AAADD27F979C77 /* Pods-iosApp.debug.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CODE_SIGN_IDENTITY = "Apple Distribution";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Manual;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
DEVELOPMENT_ASSET_PATHS = "\"iosApp/Preview Content\"";
|
DEVELOPMENT_ASSET_PATHS = "\"iosApp/Preview Content\"";
|
||||||
DEVELOPMENT_TEAM = L432S2FZP5;
|
DEVELOPMENT_TEAM = L432S2FZP5;
|
||||||
ENABLE_PREVIEWS = YES;
|
ENABLE_PREVIEWS = YES;
|
||||||
@ -373,7 +373,7 @@
|
|||||||
MARKETING_VERSION = 1.0.0;
|
MARKETING_VERSION = 1.0.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.mifospay;
|
PRODUCT_BUNDLE_IDENTIFIER = org.mifospay;
|
||||||
PRODUCT_NAME = "${APP_NAME}";
|
PRODUCT_NAME = "${APP_NAME}";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "match AdHoc org.mifospay";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
};
|
};
|
||||||
@ -384,8 +384,8 @@
|
|||||||
baseConfigurationReference = 471D4B8AF5995E32718DCCCD /* Pods-iosApp.release.xcconfig */;
|
baseConfigurationReference = 471D4B8AF5995E32718DCCCD /* Pods-iosApp.release.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CODE_SIGN_IDENTITY = "Apple Distribution";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Manual;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
DEVELOPMENT_ASSET_PATHS = "\"iosApp/Preview Content\"";
|
DEVELOPMENT_ASSET_PATHS = "\"iosApp/Preview Content\"";
|
||||||
DEVELOPMENT_TEAM = L432S2FZP5;
|
DEVELOPMENT_TEAM = L432S2FZP5;
|
||||||
ENABLE_PREVIEWS = YES;
|
ENABLE_PREVIEWS = YES;
|
||||||
@ -404,7 +404,7 @@
|
|||||||
MARKETING_VERSION = 1.0.0;
|
MARKETING_VERSION = 1.0.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.mifospay;
|
PRODUCT_BUNDLE_IDENTIFIER = org.mifospay;
|
||||||
PRODUCT_NAME = "${APP_NAME}";
|
PRODUCT_NAME = "${APP_NAME}";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "match AdHoc org.mifospay";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
};
|
};
|
||||||
|
|||||||
@ -17,11 +17,15 @@
|
|||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>1.0</string>
|
<string>1.0.0</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>6</string>
|
<string>8</string>
|
||||||
|
<key>ITSAppUsesNonExemptEncryption</key>
|
||||||
|
<false/>
|
||||||
<key>LSRequiresIPhoneOS</key>
|
<key>LSRequiresIPhoneOS</key>
|
||||||
<true/>
|
<true/>
|
||||||
|
<key>NSCameraUsageDescription</key>
|
||||||
|
<string>We use the camera to scan QR codes to send and receive payments.</string>
|
||||||
<key>NSPhotoLibraryAddUsageDescription</key>
|
<key>NSPhotoLibraryAddUsageDescription</key>
|
||||||
<string>Allow access to add photos to your library so you can save artworks directly to your device and view them offline.</string>
|
<string>Allow access to add photos to your library so you can save artworks directly to your device and view them offline.</string>
|
||||||
<key>UIApplicationSceneManifest</key>
|
<key>UIApplicationSceneManifest</key>
|
||||||
|
|||||||
@ -28,8 +28,8 @@ module FastlaneConfig
|
|||||||
key_id: "7V3ABCDEFG",
|
key_id: "7V3ABCDEFG",
|
||||||
issuer_id: "7ab9e231-9603-4c3e-a147-be3b0f123456",
|
issuer_id: "7ab9e231-9603-4c3e-a147-be3b0f123456",
|
||||||
key_filepath: "./secrets/Auth_key.p8",
|
key_filepath: "./secrets/Auth_key.p8",
|
||||||
version_number: "1.0",
|
version_number: "1.0.0",
|
||||||
metadata_path: "./fastlane/metadata",
|
metadata_path: "./fastlane/metadata/ios",
|
||||||
app_rating_config_path: "./fastlane/age_rating.json"
|
app_rating_config_path: "./fastlane/age_rating.json"
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|||||||
@ -388,6 +388,16 @@ platform :ios do
|
|||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private_lane :set_plist_values do
|
||||||
|
ios_config = FastlaneConfig::IosConfig::BUILD_CONFIG
|
||||||
|
update_plist(
|
||||||
|
plist_path: ios_config[:plist_path],
|
||||||
|
block: proc do |plist|
|
||||||
|
plist["NSCameraUsageDescription"] = "We use the camera to scan QR codes to send and receive payments."
|
||||||
|
end
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
###################
|
###################
|
||||||
# Main Public lanes
|
# Main Public lanes
|
||||||
###################
|
###################
|
||||||
@ -499,6 +509,8 @@ platform :ios do
|
|||||||
build_number: latest_build_number + 1
|
build_number: latest_build_number + 1
|
||||||
)
|
)
|
||||||
|
|
||||||
|
set_plist_values
|
||||||
|
|
||||||
build_ios_project(
|
build_ios_project(
|
||||||
options.merge(
|
options.merge(
|
||||||
provisioning_profile_name: "match AppStore org.mifospay"
|
provisioning_profile_name: "match AppStore org.mifospay"
|
||||||
@ -527,7 +539,7 @@ platform :ios do
|
|||||||
version_number: ios_config[:version_number]
|
version_number: ios_config[:version_number]
|
||||||
)
|
)
|
||||||
|
|
||||||
latest_build_number = app_store_build_number(
|
latest_build_number = latest_testflight_build_number(
|
||||||
app_identifier: options[:app_identifier] || ios_config[:app_identifier],
|
app_identifier: options[:app_identifier] || ios_config[:app_identifier],
|
||||||
api_key: Actions.lane_context[SharedValues::APP_STORE_CONNECT_API_KEY],
|
api_key: Actions.lane_context[SharedValues::APP_STORE_CONNECT_API_KEY],
|
||||||
version: ios_config[:version_number]
|
version: ios_config[:version_number]
|
||||||
@ -538,14 +550,7 @@ platform :ios do
|
|||||||
build_number: latest_build_number + 1
|
build_number: latest_build_number + 1
|
||||||
)
|
)
|
||||||
|
|
||||||
update_plist(
|
set_plist_values
|
||||||
plist_path: ios_config[:plist_path],
|
|
||||||
block: proc do |plist|
|
|
||||||
plist['NSContactsUsageDescription'] = 'This app does not access your contacts. This message is required for compliance only.'
|
|
||||||
plist['NSLocationWhenInUseUsageDescription'] = 'This app does not access your location. This message is required for compliance only.'
|
|
||||||
plist['NSBluetoothAlwaysUsageDescription'] = 'This app does not use Bluetooth. This message is required for compliance only.'
|
|
||||||
end
|
|
||||||
)
|
|
||||||
|
|
||||||
build_ios_project(
|
build_ios_project(
|
||||||
options.merge(
|
options.merge(
|
||||||
@ -555,10 +560,10 @@ platform :ios do
|
|||||||
|
|
||||||
deliver(
|
deliver(
|
||||||
metadata_path: options[:metadata_path] || ios_config[:metadata_path],
|
metadata_path: options[:metadata_path] || ios_config[:metadata_path],
|
||||||
submit_for_review: true, # Set to true if you want to auto-submit for review
|
submit_for_review: false, # Set to true if you want to auto-submit for review
|
||||||
automatic_release: true, # Set to true if you want to auto-release once it approved
|
automatic_release: true, # Set to true if you want to auto-release once it approved
|
||||||
api_key: Actions.lane_context[SharedValues::APP_STORE_CONNECT_API_KEY],
|
api_key: Actions.lane_context[SharedValues::APP_STORE_CONNECT_API_KEY],
|
||||||
skip_app_version_update: true,
|
skip_app_version_update: false,
|
||||||
force: true, # Skips HTML report verification
|
force: true, # Skips HTML report verification
|
||||||
precheck_include_in_app_purchases: false,
|
precheck_include_in_app_purchases: false,
|
||||||
overwrite_screenshots: true,
|
overwrite_screenshots: true,
|
||||||
|
|||||||
16
fastlane/age_rating.json
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"violenceCartoonOrFantasy": "NONE",
|
||||||
|
"violenceRealistic": "NONE",
|
||||||
|
"violenceRealisticProlongedGraphicOrSadistic": "NONE",
|
||||||
|
"profanityOrCrudeHumor": "NONE",
|
||||||
|
"matureOrSuggestiveThemes": "NONE",
|
||||||
|
"horrorOrFearThemes": "NONE",
|
||||||
|
"sexualContentGraphicAndNudity": "NONE",
|
||||||
|
"alcoholTobaccoOrDrugUseOrReferences": "NONE",
|
||||||
|
"gamblingSimulated": "NONE",
|
||||||
|
"sexualContentOrNudity": "NONE",
|
||||||
|
"contests": "NONE",
|
||||||
|
"medicalOrTreatmentInformation": "NONE",
|
||||||
|
"unrestrictedWebAccess": false,
|
||||||
|
"gambling": false
|
||||||
|
}
|
||||||
101
fastlane/app_privacy_details.json
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"category": "CONTACTS",
|
||||||
|
"purposes": [
|
||||||
|
"APP_FUNCTIONALITY"
|
||||||
|
],
|
||||||
|
"data_protections": [
|
||||||
|
"DATA_LINKED_TO_YOU"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"category": "CREDIT_AND_FRAUD",
|
||||||
|
"purposes": [
|
||||||
|
"APP_FUNCTIONALITY"
|
||||||
|
],
|
||||||
|
"data_protections": [
|
||||||
|
"DATA_LINKED_TO_YOU"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"category": "DEVICE_ID",
|
||||||
|
"purposes": [
|
||||||
|
"APP_FUNCTIONALITY"
|
||||||
|
],
|
||||||
|
"data_protections": [
|
||||||
|
"DATA_LINKED_TO_YOU"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"category": "EMAIL_ADDRESS",
|
||||||
|
"purposes": [
|
||||||
|
"APP_FUNCTIONALITY"
|
||||||
|
],
|
||||||
|
"data_protections": [
|
||||||
|
"DATA_LINKED_TO_YOU"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"category": "NAME",
|
||||||
|
"purposes": [
|
||||||
|
"APP_FUNCTIONALITY"
|
||||||
|
],
|
||||||
|
"data_protections": [
|
||||||
|
"DATA_LINKED_TO_YOU"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"category": "OTHER_FINANCIAL_INFO",
|
||||||
|
"purposes": [
|
||||||
|
"APP_FUNCTIONALITY"
|
||||||
|
],
|
||||||
|
"data_protections": [
|
||||||
|
"DATA_LINKED_TO_YOU"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"category": "PAYMENT_INFORMATION",
|
||||||
|
"purposes": [
|
||||||
|
"APP_FUNCTIONALITY"
|
||||||
|
],
|
||||||
|
"data_protections": [
|
||||||
|
"DATA_LINKED_TO_YOU"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"category": "PHONE_NUMBER",
|
||||||
|
"purposes": [
|
||||||
|
"APP_FUNCTIONALITY"
|
||||||
|
],
|
||||||
|
"data_protections": [
|
||||||
|
"DATA_LINKED_TO_YOU"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"category": "PHOTOS_OR_VIDEOS",
|
||||||
|
"purposes": [
|
||||||
|
"APP_FUNCTIONALITY"
|
||||||
|
],
|
||||||
|
"data_protections": [
|
||||||
|
"DATA_LINKED_TO_YOU"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"category": "PHYSICAL_ADDRESS",
|
||||||
|
"purposes": [
|
||||||
|
"APP_FUNCTIONALITY"
|
||||||
|
],
|
||||||
|
"data_protections": [
|
||||||
|
"DATA_LINKED_TO_YOU"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"category": "USER_ID",
|
||||||
|
"purposes": [
|
||||||
|
"APP_FUNCTIONALITY"
|
||||||
|
],
|
||||||
|
"data_protections": [
|
||||||
|
"DATA_LINKED_TO_YOU"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
3
fastlane/metadata/ios/copyright.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
© 2025 The Mifos Initiative
|
||||||
|
|
||||||
|
This app is licensed under the Mozilla Public License, v. 2.0.
|
||||||
1
fastlane/metadata/ios/en-US/apple_tv_privacy_policy.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
|
||||||
16
fastlane/metadata/ios/en-US/description.txt
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
Mifos Pay is a simple, secure way to send, request, and track money. Create a wallet account, add a card, share a QR to get paid, set standing instructions for recurring transfers, and manage invoices—all from one clean, modern app.
|
||||||
|
|
||||||
|
WHAT YOU CAN DO
|
||||||
|
• Sign up as a customer or merchant and complete a guided registration
|
||||||
|
• Create a wallet savings account (subject to approval) and see your balance at a glance
|
||||||
|
• Send money using a Virtual Payment Address (VPA), mobile number, or account number
|
||||||
|
• Request money with your personal QR code; optionally set the amount and currency before sharing
|
||||||
|
• Add and manage cards; view masked details and remove or edit when needed
|
||||||
|
• Track everything in Payments: filter History by debits or credits, view statements, and see real-time notifications
|
||||||
|
• Set SI (Standing Instructions) for automatic transfers on a fixed schedule (weeks, months, years)
|
||||||
|
• Create and review invoices; see invoice status, items, and transaction IDs
|
||||||
|
• Keep profile details up to date—name, address, phone, VPA—and link a bank account
|
||||||
|
• Upload documents for KYC or support directly in the app
|
||||||
|
• Get help fast with built-in FAQs
|
||||||
|
|
||||||
|
|
||||||
1
fastlane/metadata/ios/en-US/keywords.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
wallet,payments,transfer,sendmoney,QRpay,invoice,card,linkbank,KYC,merchant
|
||||||
1
fastlane/metadata/ios/en-US/marketing_url.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
|
||||||
1
fastlane/metadata/ios/en-US/name.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
Mifos Pay
|
||||||
1
fastlane/metadata/ios/en-US/privacy_url.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
https://openmf.github.io/privacy_policy_mifos_mobile.html
|
||||||
1
fastlane/metadata/ios/en-US/promotional_text.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
Send and receive money, pay merchants, and track transactions with an open-source wallet powered by Mifos X / Fineract.
|
||||||
1
fastlane/metadata/ios/en-US/release_notes.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
|
||||||
1
fastlane/metadata/ios/en-US/subtitle.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
Open-source digital wallet
|
||||||
1
fastlane/metadata/ios/en-US/support_url.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
https://github.com/openMF/mobile-wallet
|
||||||
1
fastlane/metadata/ios/primary_category.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
Finance
|
||||||
1
fastlane/metadata/ios/primary_first_sub_category.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
|
||||||
1
fastlane/metadata/ios/primary_second_sub_category.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
|
||||||
@ -0,0 +1 @@
|
|||||||
|
@Venus@2025@
|
||||||
1
fastlane/metadata/ios/review_information/demo_user.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
venus
|
||||||
@ -0,0 +1 @@
|
|||||||
|
info@mifos.org
|
||||||
1
fastlane/metadata/ios/review_information/first_name.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
Hekmatullah
|
||||||
1
fastlane/metadata/ios/review_information/last_name.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
Amin
|
||||||
1
fastlane/metadata/ios/review_information/notes.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
|
||||||
@ -0,0 +1 @@
|
|||||||
|
+44 7391462187
|
||||||
1
fastlane/metadata/ios/secondary_category.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
Utilities
|
||||||
1
fastlane/metadata/ios/secondary_first_sub_category.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
|
||||||
1
fastlane/metadata/ios/secondary_second_sub_category.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
|
||||||
BIN
fastlane/screenshots/en-US/0_APP_IPHONE_65_0.png
Normal file
|
After Width: | Height: | Size: 734 KiB |
BIN
fastlane/screenshots/en-US/1_APP_IPAD_PRO_3GEN_129_1.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
fastlane/screenshots/en-US/1_APP_IPHONE_65_1.png
Normal file
|
After Width: | Height: | Size: 873 KiB |
BIN
fastlane/screenshots/en-US/2_APP_IPAD_PRO_3GEN_129_2.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
fastlane/screenshots/en-US/2_APP_IPHONE_65_2.png
Normal file
|
After Width: | Height: | Size: 727 KiB |
BIN
fastlane/screenshots/en-US/3_APP_IPAD_PRO_3GEN_129_3.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
fastlane/screenshots/en-US/3_APP_IPHONE_65_3.png
Normal file
|
After Width: | Height: | Size: 523 KiB |
BIN
fastlane/screenshots/en-US/4_APP_IPAD_PRO_3GEN_129_4.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
fastlane/screenshots/en-US/4_APP_IPHONE_65_4.png
Normal file
|
After Width: | Height: | Size: 482 KiB |
BIN
fastlane/screenshots/en-US/5_APP_IPAD_PRO_3GEN_129_5.png
Normal file
|
After Width: | Height: | Size: 1023 KiB |